检查是否[NSObject:AnyObject]!是斯威夫特的{N'Null

时间:2016-05-10 09:51:56

标签: 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"总是失败"

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

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

2 个答案:

答案 0 :(得分:2)

首先,如果变量可以包含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;
}

或在setter中

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

正如您所看到的,有多种解决方案,但最佳解决方案甚至可以改进您的Obj-C代码。 NSNullnil之间的差异应该在本地处理,而不是传播。

答案 1 :(得分:1)

如果您要验证currentDictionary是否为nil,可以使用:

guard let currentDictionary = DataManager.sharedManager().currentDictionary else {
    return
}

如果您不想提前退回,请将guard-else语句替换为if-else

如果您要验证currentDictionary的内容是否为NSNull

if let value = DataManager.sharedManager().currentDictionary["key"] {
    // do something with value
}