I keep getting asked the same question and each time, even though I know the basics, I stumble my way to a precarious explanation. Even my grandmother who can’t operate a toaster oven would realize that there’s something shady about my arguments. So this time, I decided to write it down and here it goes…
First, I’ll preface with what (almost) everyone knows. From a compiler standpoint, NULL, nil and Nil are interchangeable because they are all defined as zero. This is because in MacTypes.h and NSObjCRuntime.h, you’ll find:
#define nil NULL
#define Nil NULL
and in the standard C library, stddef.h:
#define NULL ((void *)0)
So ultimately, every is defined as zero therefore the compiler doesn’t care what representation of zero you use, it’s still the same value. Actually in your code, you could just use 0 instead of NULL, or even use FALSE, or NO. But that would just be ugly because you are losing the semantic meaning of the word NULL, which is used to represent ‘no value’. After all, we want to be able to read the code and understand what the programmer meant.
This is exactly why there are multiple names for a null pointer. While they all have the same value, they mean something different to the programmer who reads the code.
NULL comes from the C world. This is why it is defined in the standard C libraries. You should use NULL in your code when you want to set a C pointer to ‘no value’.
nil and Nil are used exclusively in the Objective-C world. You use nil to point an Objective-C object to ‘no value’ and Nil to point an Objective-C class to ‘no value’.
Lastly, there is NSNull. NSNull is a real object, with a non-zero value. It is not interchangeable with the others. Instead it is used to represent a null where a non-null value is required. Typically, you would use NSNull if you want to represent null entries in a collection:
[mutableArray addObject:[NSNull null]];
The main debate is usually around the use of nil vs. NULL. My take on this is that if you are pointing an Objective-C object to ‘no value’, then use nil. For everything else (which really mostly amounts to selectors and void* ), use NULL.
So if you take a look at NSAlert
- (void)beginSheetModalForWindow:(NSWindow *)window modalDelegate:(id)modalDelegate didEndSelector:(SEL)alertDidEndSelector contextInfo:(void *)contextInfo
If you wanted to call this and set all the arguments to no value, you would do:
[alert beginSheetModelForWindow:nil modalDelegate:nil
You rarely find yourself wondering if you should use Nil, but here’s one case. The NSObject class defines the method:
So you’d call:
And there you have it… Even if you too can’t operate a toaster oven, you will at least know when to use the proper semantic…