views:

412

answers:

9

Currently I understand it as a kind of "empty object". But what's it really?

+3  A: 

It's "nothing". But a "nothing" you can send messages to without getting killed as you would if you were trying to call a method on NULL.

You can look at this question to have more info on NULL vs. nil

Romain
You can send messages to `NULL` if you like to, it behaves exactly the same as `nil` because both are just the value `0` to the computer. I even think that `nil` is typedefd as `NULL`.
Georg
`Nil`, `nil` and `NULL` are all defined as `__DARWIN_NULL` and therefore completely interchangeable. But there are some logical differences.
Georg
If you read my statement very carefully, you'll note I **never** say you'll get a crash or any issue sending a message to `NULL`. I've been very positively saying "calling a method on `NULL`" for that very specific reason. However, be they as interchangeable as they can, I believe the semantics of each needs to translate in code.Just because you *can* do crappy coding doesn't mean you *should*.
Romain
+2  A: 

It's a null pointer - a pointer to "nothing".

Joshua Nozzi
A: 

Maybe I'm just missing the obvious but this seems like a semantic question. As in, you can use lots of different words to describe it, but your description works well enough already.

http://en.wikipedia.org/wiki/Null%5F%28computer%5Fprogramming)

Amber Shah
+5  A: 

nil should only be used with pointers, and nil represents a pointer which points to nothing (it's value is zero)

NSString *myString = nil; // myString points to nothing
int x = nil; // invalid, "x" is not a pointer, but it will compile
Philippe Leybaert
+11  A: 

It's not an empty object, it's the lack of any object at all. The rest of the answers cover the other semantics, so I'll leave it at that :)

Steven Schlansker
This is by far the best answer.
Georg
+1  A: 

Formally defined, it is as Joshual defined - a pointer to nothing or a pointer to no object at all.

From a practical, implementation perspective, particularly when dealing with data structures and algorithms, a nill often will represent a sentinel in a data structure or an object that represents "nothing" for example, in a red-black tree, technically, all of the leaf nodes are "nill", but they still have the same or similar properties & operations of a leaf node (color, pointer to a parent, etc.) - in those cases, it is really a "nothing object" ... if that makes any sense.

So, formally, it is a pointer to nothing, in practice, it is often treated as a representation of nothing, but it is never ... null.

James Conigliaro
+1  A: 

One useful way of thinking about nil is imagining that it's the empty object that "does nothing".

By "does nothing" I mean, any message you send it won't have side effects.

It's "empty" in the sense that when you ask it for the value of any property, it always returns nil. So it's not holding any values --> it's empty.
(Actually, it's a little more complicated than that, when you ask for the value of a property that returns a type that's NOT an obj-c object. You will get back a pointer-sized 0. So for any scalar values that are no larger than sizeof(void*) you get 0. But if you ask for a struct or a double on a 32 bit system, you get an undefined result. I've written about this here.)

Vincent Gable
A: 

Just to clarify, in Objective-C nil and null are not the same thing. Neither do they represent the same thing in Objective-C as they do in mathematics or other programming languages.

Nil is actually a special memory address of 0x0 (at least the compiler treats it as an address.) Nil is used as the address of an object that is named but not allocated. This allows for test for the existence/allocation of named objects as well as providing a safe way to send messages to objects that might not exist. While in math and some languages you can compare scalar variables to nil, in Objective-c, you should not. You should only compare the address of objects.

NULL by contrast can mean either the standard C defined as an integer value ofNULL==0 or it can represents an actual allocated object of the class NSNull with a specific address in memory. NSNull is however, a singleton object i.e. only one exist for every application. It is used as placeholder for other objects usually in collections. You cannot use it in comparisons with any other object. You can only check if a particular pointer points to the singleton NSNull object. Note however that as an allocated object[NSNull null]!=NULL,

The confusion between nil and NULL arises because assigning an address of NULL assigns it to the nil address of 0x0. Such code works but can cause subtle problem at times. It's best to get in the habit of not confusing the two.

So, in Objective-C, nil, NUll and NSNull are three different but overlapping concepts that are easy to confuse. Nil should be used for addresses, NULL should be used for scalar values and NSNull should be used as a placeholder for allocated objects.

TechZen
I'm pretty certain that there are _no_ cases where one cannot exchange `nil` with `NULL`. Both are just the value `0x0`.
Georg
In C, `NULL` is normally defined as a `(void*)`, not an integer. C++ differs on this for reasons not worth going into, but in both languages `NULL` is conventionally used for pointer types only. NULL is *not* scalar and should not be used as such.
walkytalky
It's stylistic matter. It's bad practice to substitute NULL for nil because NULL is often used to mean undefined. For example, in SQL NULL has a special meaning.
TechZen
+13  A: 

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-existant class: Class someClass = Nil.
  • nil is used as a non-existant instance: id someInstance = nil.
  • NULL is a pointer to a non-existant memory part: char *theString = NULL.

Short

nil isn't an empty object but a non-existant 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
Georg
It is perfectly valid to compare a pointer variable to `nil`. You might even argue that it's more explicitly a `nil`-check than the mere pointer-as-truth-expression (although I use the truth-expression form myself).
Peter Hosey
Yes, but I argue that if one uses "no object" as the analogy to `nil`, it's logically not possible to compare "no object" to "no object", but it's easy to say "do this _if this object exists_".
Georg
Yes, `if (nil == nil)` doesn't make sense, but `if (anObject == nil)` does: “If no object is in the variable `anObject`…”
Peter Hosey
I do not think of it as "variable that contains `anObject`" normally but just as `anObject`. This simplification works most of the time. As soon as you think of it as `pointer to an object` comparing it to `nil` makes perfect sense.
Georg