1

if object set to nil and I want to check for its value.

if object != nil {
  // do something
}

or

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

I guess the second condition will be triggered but I am not sure why.

Can someone explain please?

1
  • 1
    nil is nothing & you cannot check the value of nothing, in contrast NSNull is literally an object & its value is nil. Commented Oct 25, 2018 at 3:00

3 Answers 3

3

If you want to make sure object isn't nil and it isn't NSNull null then do:

if (object && object != [NSNull null]) {
    // do something with object
} // else it's either nil or NSNull null
Sign up to request clarification or add additional context in comments.

Comments

2

As others have pointed out, object != nil && object != NSNull.null would give you the expected behaviour, however it might be tedious and error prone to write this pair of conditions every time.

Alternatively you can use inverted logic, by adding an nonNullValue method to virtually almost all objects in the system:

// 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

you can then simply use it on your pointers:

// 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
}

This approach is a little bit invasive as it touches all NSObject subclasses, however it eliminates the need of writing multiple conditions.

Comments

1

The difference between [NSNull null] and nil is that nil is an empty object that has completely disappeared from memory, and we use [NSNull null] when we want to express the idea that "we need a container that has nothing in it," which is "an object whose value is null." If you look up the development documentation you'll see that the class NSNull inherits NSObject and has only one "+ (NSNull *) null;" Class methods. This means that the NSNull object has a valid memory address, so any reference to it in the program will not cause the program to crash.

3 Comments

nil is simply a pointer that points to no object. It it no "an empty object that has completely disappeared from memory".
Yeah, I use NSLog(@"nil=== %p",nil); NSLog(@"null==== =%p",[NSNull null]) is printed on the console, resulting in nil====0x0, null====0x1022c2f08.
I downvoted this due to the "nil is an empty object that has completely disappeared from memory", as others have pointed out this affirmation is incorrect . Once that part gets rephrased I will gladly retract my downvote.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.