68

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

 (
    "< 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
4

9 回答 9

124
id object = myArray[0];// similar to [myArray objectAtIndex:0]

if(![object isEqual:[NSNull null]])
{
    //do something if object is not equals to [NSNull null]
}
于 2013-09-27T20:17:33.560 回答
30
if (myArray != (id)[NSNull null])

或者

if(![myArray isKindOfClass:[NSNull class]]) 
于 2013-09-27T20:18:24.373 回答
14

根据托尼的回答,我做了一个宏。

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

然后使用它

if (isNSNull(dict[@"key"])) ...
于 2014-04-22T15:37:01.007 回答
8

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

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

我敢肯定有更好的答案,但这一个有效。

于 2015-11-11T22:56:08.700 回答
7

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

  • 看起来又吵又丑。
  • 耗时的。
  • 容易出错。

所以我创建了以下类别:

@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(即该类型的单例实例Class),则行为未定义。但是,允许在子类中声明的方法覆盖其超类中的类别方法。

这允许更简洁的代码:

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

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

于 2015-04-17T06:49:19.763 回答
4

您可以使用以下检查:

if (myArray[0] != [NSNull null]) {
    // Do your thing here
}

原因可以在 Apple 的官方文档中找到:

使用 NSNull

NSNull 类定义了一个单例对象,用于在禁止将 nil 作为值的情况下(通常在数组或字典等集合对象中)表示空值。

NSNull *nullValue = [NSNull null];
NSArray *arrayWithNull = @[nullValue];
NSLog(@"arrayWithNull: %@", arrayWithNull);
// Output: "arrayWithNull: (<null>)"

重要的是要理解 NSNull 实例在语义上与 NO 或 false 不同——它们都代表一个逻辑值;NSNull 实例表示没有值。NSNull 实例在语义上等同于 nil,但同样重要的是要认识到它不等于 nil。因此,要测试空对象值,您必须进行直接对象比较。

id aValue = [arrayWithNull objectAtIndex:0];
if (aValue == nil) {
    NSLog(@"equals nil");
}
else if (aValue == [NSNull null]) {
    NSLog(@"equals NSNull instance");
    if ([aValue isEqual:nil]) {
        NSLog(@"isEqual:nil");
    }
}
// Output: "equals NSNull instance"

取自https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/NumbersandValues/Articles/Null.html

于 2018-05-15T03:02:08.723 回答
3

已经给出了很多好的和有趣的答案,并且(几乎)所有答案都有效。

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

[NSNull null] 被记录为返回单例。所以

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

工作也很好。

但是,由于这是一个例外,我不认为使用 == 来比较对象通常是一个好主意。(如果我要查看您的代码,我肯定会对此发表评论)。

于 2016-10-13T07:39:41.750 回答
2

在 Swift(或从 Objective-C 桥接)中,可以有NSNullnil在一个可选数组中。 NSArrays 只能包含对象并且永远不会有nil,但可能有NSNull。然而,一个 SwiftAny?类型数组可能包含nil.

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

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

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

您还可以使用if letorguard来检查您的对象是否可以转换为NSNull

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

或者

if let _ = obj as? NSNull {
    // obj is NSNull
}
于 2016-02-29T20:42:53.720 回答
2

考虑这种方法:

选项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.
} 
于 2017-07-28T09:05:27.640 回答