Objective-C objects
First of all, when you call this:
id someObject = [NSArray array];
someObject
isn't the array object directly but only a pointer to it. That means, if someObject
is equal to 0x1234
there's an object at that address in the memory.
That's the reason why
id someOtherObject = someObject;
doesn't copy the object. Both pointers point now to the same object.
Pointer to 0x0
So, how is nil
defined? Let's take a look at the source code:
objc.h
#define nil __DARWIN_NULL /* id of Nil instance */
_types.h
#ifdef __cplusplus
…
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */
Looks like nil
is a pointer to the address 0x0.
So what?
Let's see what the Objective-C Programming Reference has to say:
Sending Messages to nil
In Objective-C, it is valid to send a
message to nil—it simply has no effect
at runtime. There are several patterns
in Cocoa that take advantage of this
fact. The value returned from a
message to nil may also be valid: …
The returned values are either nil
, 0 or a struct
with all variables initialized to 0. Which one it is depends on the expected return type. There is an explicit check in the objective-c runtime for messages to nil
, that means it's really fast.
Nil
, nil
, NULL
Those are the 3 types. Here are all the definitions:
#define Nil __DARWIN_NULL /* id of Nil class */
#define nil __DARWIN_NULL /* id of Nil instance */
#define NULL __DARWIN_NULL
#define __DARWIN_NULL ((void *)0)
As can be seen, they are all exactly the same. Nil
and nil
are defined by Objective-C, NULL
comes from C.
What's the difference then? It's only about style. It makes the code more readable.
Nil
is used as a non-existent class: Class someClass = Nil
.
nil
is used as a non-existent instance: id someInstance = nil
.
NULL
is a pointer to a non-existent memory part: char *theString = NULL
.
Short
nil
isn't an empty object but a non-existent one. A method -getSomeObject
doesn't return an empty object if it doesn't exist but returns nil
which tells the user that there is no object.
Maybe this makes sense: (Both would compile and run.)
if (anObject == nil) { // One cannot compare nothing to nothing,
// that wouldn't make sense.
if (anObject) { // Correct, one checks for the existence of anObject