检查对象是否等于 nil 或 [NSNull null]

Check object if it's equal to nil or to [NSNull null]

提问人:Pavel Bogart 提问时间:10/25/2018 最后编辑:Pavel Bogart 更新时间:10/25/2018 访问量:1191

问:

如果对象设置为 nil,我想检查它的值。

if object != nil {
  // do something
}

if object != [NSNull null] {
  // do something
}

我想第二个条件会被触发,但我不确定为什么。

有人可以解释一下吗?

objective-c null

评论

1赞 RyanB 10/25/2018
nil什么都不是,你不能检查 的值,相比之下,它实际上是一个对象,它的值是 。nothingNSNullnil

答:

1赞 rmaddy 10/25/2018 #1

如果你想确保不是,它不是,那么做:objectnilNSNull null

if (object && object != [NSNull null]) {
    // do something with object
} // else it's either nil or NSNull null
1赞 Cristik 10/25/2018 #2

正如其他人所指出的,会给你预期的行为,但是每次都写这对条件可能很乏味且容易出错。object != nil && object != NSNull.null

或者,您可以使用反转逻辑,方法是向系统中的几乎所有对象添加方法:nonNullValue

// in some header file
@interface NSObject(NullExtension)
- (instancetype)nonNullValue;
@end

// in some implementation file    
@implementation NSObject(NullExtension)

// regular objects are not null (right?)
- (instancetype)nonNullValue {
    return self;
}
@end

@implementation NSNull(NullExtension)

// let's make NSNull report as being null
- (instancetype)nonNullValue {
    return nil;
}
@end

// adding this just for the sake of completeness, it's highly unlikely
// that JSON's will decode NSProxy instances
@implementation NSProxy(NullExtension)

- (instancetype)nonNullValue {
    return self;
}
@end

然后,您可以简单地在指针上使用它:

// since we're in Objective-C, a nil pointer will always fail the check
// and thanks to the NSNull extension, NSNull instances will behave the same
if ([object nonNullValue] != nil) {
    // NSNull won't get here
    // nils won't get here
    // other objects will get here
}

这种方法有点侵入性,因为它涉及所有子类,但它消除了编写多个条件的需要。NSObject

1赞 JackySong 10/25/2018 #3

[NSNull null] 和 nil 的区别在于 nil 是一个完全从内存中消失的空对象,当我们想表达“我们需要一个什么都没有的容器”的想法时,我们使用 [NSNull null],即“一个值为 null 的对象”。如果查找开发文档,将看到类 NSNull 继承了 NSObject,并且只有一个“+ (NSNull *) null;”类方法。这意味着 NSNull 对象具有有效的内存地址,因此在程序中对它的任何引用都不会导致程序崩溃。

评论

1赞 rmaddy 10/25/2018
nil只是一个指向任何对象的指针。它不是“一个完全从记忆中消失的空物体”。
0赞 JackySong 10/26/2018
是的,我使用 NSLog(@“nil=== %p”,nil);NSLog(@“null==== =%p”,[NSNull null]) 打印在控制台上,结果为 nil====0x0, null====0x1022c2f08。
0赞 Cristik 12/5/2019
我对此投了反对票,因为“零是一个完全从记忆中消失的空对象”,因为其他人指出这种肯定是不正确的。一旦那部分被重新表述,我很乐意收回我的反对票。