objective-c - 在 Swift 中检查 [NSObject : AnyObject]! 是否为 NSNull

标签 objective-c swift type-safety

我的项目同时使用 Swift 和 Objective C。我有一个用 Objective C 编写的单例,它作为 NSDictionary 类型的属性。

@property(nonatomic, strong) NSDictionary *currentDictionary;

这是一个在我的整个项目中都在使用的旧类。我正在尝试在这样的 Swift 类中使用此类

if let dict = DataManager.sharedManager().currentDictionary
{
   // 
}

我面临的问题是 currentDictionary 是使用来自服务器的数据设置的。有时这可能是

在 Objective C 类中,我可以通过以下检查来处理这种情况

if ([currentDictionary isKindOfClass: [NSNull class]])
{
   // Do nothing
}

但我不确定如何在 Swift 中实现类似的检查。我尝试了以下

if let data = DataManager.sharedManager().currentDictionary as? NSNull
{
    return 
}

但它不起作用,而且我收到编译器警告:

“从“[NSObject : AnyObject]!”转换为无关类型“NSNull”总是失败”

这不同于检查字典中的 Null 值,因为它们将是“AnyObject”,我可以尝试将它们转换为我想要检查的类型。

有人可以提供有关如何正确处理这种情况的任何指示

最佳答案

首先,如果变量可以包含NSDictionary 之外的内容,请不要将其类型设置为NSDictionary。 Swift 是类型安全的,它会信任声明的类型。

最简单的解决方法是在 Objective-C 中将其设为 id

然后在 Swift 中你可以简单地:

guard let data = DataManager.sharedManager().currentDictionary as? NSDictionary else {
    return 
}

如果您无法更改原始代码,只需使用类别创建具有正确类型的 Swift 访问器,例如

@interface DataManager (Swift)

// solution 1, will be converted to AnyObject in Swift
- (id)currentDictionaryForSwift1;

// solution 2, let's handle NSNull internally, don't propagate it to Swift
- (NSDictionary *)currentDictionaryForSwift2;

@end

@implementation DataManager

- (id)currentDictionaryForSwift1 {
   return self.currentDictionary;
}  

- (NSDictionary *)currentDictionaryForSwift2 {
   if (self.currentDictionary == [NSNull null]) { 
      return nil;
   }

   return self.currentDictionary;
}    

@end

我建议您在内部处理 NSNull。其他代码应该不需要分别处理 nilNSNull

你实际上可以在 getter 中解决它:

- (NSDictionary *)currentDictionary {
   if (_currentDictionary == [NSNull null]) {
      return nil;
   }

   return _currentDictionary;
}

或在二传手中

- (void)setCurrentDictionary:(NSDictionary *)currentDictionary {
    if (currentDictionary == [NSNull null]) {
       _currentDictionary = nil;
    } else {
       _currentDictionary = currentDictionary;
    }
}

如您所见,有多种解决方案,但最好的解决方案甚至应该改进您的 Obj-C 代码。 NSNullnil 之间的区别应该在本地处理,而不是传播。

关于objective-c - 在 Swift 中检查 [NSObject : AnyObject]! 是否为 NSNull,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37134961/

相关文章:

ios - 更改 UISearchController 的 UINavigationBar 背景色

android - 安全参数 : cannot resolve symbol 'string'

java - 检查条件安全性并在同一 if 语句中进行评估

ios - 如何在升级后的应用程序中检索 NSUserDefault 值?

ios - 轻扫弹出使图像抖动

swift - 为已编译模块自动生成 Swift 接口(interface)

Java 编译器忽略类型安全

objective-c - ExtAudioFileWrite仅写入文件的第一位

ios - 将 zlib 压缩的 base64 字符串转换为 Uiimage 时出现问题

ios - Facebook 帖子的权限是 "Only me"使用 FBWebDialogs