我如何检查NSArray中的对象是否是NSNull?

我得到一个空值的数组。 请检查我的数组结构:

( "< null>" ) 

当我试图访问索引0因为崩溃

 -[NSNull isEqualToString:]: unrecognized selector sent to instance 0x389cea70 

目前由于该数组崩溃而崩溃:

  *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull isEqualToString:]: unrecognized selector sent to instance 0x389cea70' *** First throw call stack: (0x2d9fdf53 0x3820a6af 0x2da018e7 0x2da001d3 0x2d94f598 0x1dee57 0x1dfd31 0x302f598d 0x301a03e3 0x3052aeed 0x3016728b 0x301659d3 0x3019ec41 0x3019e5e7 0x30173a25 0x30172221 0x2d9c918b 0x2d9c865b 0x2d9c6e4f 0x2d931ce7 0x2d931acb 0x3262c283 0x301d3a41 0xabb71 0xabaf8) libc++abi.dylib: terminating with uncaught exception of type NSException 
 id object = myArray[0];// similar to [myArray objectAtIndex:0] if(![object isEqual:[NSNull null]]) { //do something if object is not equals to [NSNull null] } 
 if (myArray != (id)[NSNull null]) 

要么

 if(![myArray isKindOfClass:[NSNull class]]) 

以托尼的回答为基础,我做了一个macros观。

 #define isNSNull(value) [value isKindOfClass:[NSNull class]] 

然后使用它

 if (isNSNull(dict[@"key"])) ... 

Awww,伙计们。 这是个简单的。

 // if no null values have been returned. if ([myValue class] == [NSNull class]) { myValue = nil; } 

我相信有更好的答案,但这个工作。

我发现使用NSNull的代码有以下问题:

  • 看起来嘈杂和丑陋。
  • 耗时的。
  • 容易出错。

所以我创build了以下类别:

 @interface NSObject (NSNullUnwrapping) /** * Unwraps NSNull to nil, if the object is NSNull, otherwise returns the object. */ - (id)zz_valueOrNil; @end 

随着实施:

 @implementation NSObject (NSNullUnwrapping) - (id)zz_valueOrNil { return self; } @end @implementation NSNull (NSNullUnwrapping) - (id)zz_valueOrNil { return nil; } @end 

它遵循以下规则:

  • 如果一个类被声明了两次相同的Class (即Classtypes的单例实例),那么行为是不确定的。 但是,允许在子类中声明的方法覆盖其超类中的类别方法。

这允许更简洁的代码:

 [site setValue:[resultSet[@"main_contact"] zz_valueOrNil] forKey:@"mainContact"]; 

。 。 而不是有额外的行来检查NSNullzz_前缀看起来有点难看,但为避免命名空间冲突,安全起见。

在Swift中(或从Objective-C桥接),可能有一个NSNullnil在一个可选项的数组中。 NSArray只能包含对象,不会NSNull ,但可能有NSNullAny?一个Swift数组Any? types可能包含nil ,但是。

 let myArray: [Any?] = [nil, NSNull()] // [nil, {{NSObject}}], or [nil, <null>] 

要检查NSNull ,使用is检查一个对象的types。 这个过程对于Swift数组和NSArray对象是一样的:

 for obj in myArray { if obj is NSNull { // object is of type NSNull } else { // object is not of type NSNull } } 

你也可以使用if letguard来检查你的对象是否可以被转换成NSNull

 guard let _ = obj as? NSNull else { // obj is not NSNull continue; } 

要么

 if let _ = obj as? NSNull { // obj is NSNull } 

已经有很多好的和有趣的答案已经被提出,并且(所有的)都工作。

只是为了完成(和它的乐趣):

logging[NSNull null]返回一个单例。 因此

 if (ob == [NSNull null]) {...} 

工作也很好。

然而,因为这是一个例外,我不认为使用==比较对象是一个好主意。 (如果我会检查你的代码,我肯定会对此发表评论)。

考虑这种方法:

选项1:

 NSString *str = array[0]; if ( str != (id)[NSNull null] && str.length > 0 { // you have a valid string. } 

选项2:

 NSString *str = array[0]; str = str == (id)[NSNull null]? nil : str; if (str.length > 0) { // you have a valid string. }