nil / Nil / NULL / NSNull

Understanding the concept of nothingness is as much a philosophical issue as it is a pragmatic one. We are inhabitants of a universe of somethings, yet reason in a logical universe of ontological uncertainties. As a physical manifestation of a logical system, computers are faced with the intractable problem of how to represent nothing with something.

In Objective-C, there are a few different varieties of nothing: NULL, nil, Nil, and NSNull.

Symbol Value Meaning
NULL (void *)0 literal null value for C pointers
nil (id)0 literal null value for Objective-C objects
Nil (Class)0 literal null value for Objective-C classes
NSNull [NSNull null] singleton object used to represent null

NULL

C represents nothing as 0 for primitive values and NULL for pointers (which is equivalent to 0 in a pointer context).

The only time you see NULL in Objective-C code is when interacting with low-level C APIs like Core Foundation or Core Graphics.

nil

Objective-C builds on C’s representation of nothing by adding nil. nil is an object pointer to nothing. Although semantically distinct from NULL, they are technically equivalent.

Perhaps the most notable behavior of nil, however, is that it can have messages sent to it without a problem. In other languages, like Java, this kind of behavior would crash your program. But in Objective-C, invoking a method on nil returns a zero value — which is to say, nil begets nil. This fact alone significantly simplifies things for Objective-C developers, as it obviates the need to check for nil before doing anything:

// For example, this expression...
if (name != nil && [name isEqualToString:@"Steve"]) { ... }

// ...can be simplified to:
if ([name isEqualToString:@"Steve"]) { ... }

With vigilance, this quirk of Objective-C can be a convenient feature rather than a lurking source of bugs in your application.

Nil

In addition to nil, the Objective-C runtime defines Nil as a class pointer to nothing. This lesser-known title-case cousin of nil doesn’t show up much very often, but it’s at least worth noting.

NSNull

On the framework level, Foundation defines NSNull. NSNull defines a class method (+null) that returns the singleton NSNull object. NSNull represents nothing with an actual object rather than a zero value like nil or NULL.

NSNull is used throughout Foundation and other frameworks to skirt around the limitations of collections like NSArray and NSDictionary not being able to contain nil values. You can think of NSNull as effectively boxing the NULL or nil value so that it can be used in collections:

NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary];
mutableDictionary[@"someKey"] = [NSNull null];
NSLog(@"%@", [mutableDictionary allKeys]);
// @[@"someKey"]

Why does Objective-C have four values for nothing when one might suffice? It all goes back to a common refrain, about how Objective-C bridges the procedural paradigm of C with Smalltalk-inspired object-oriented paradigm.

In the procedural world of C, values are indistinguishable from their numeric value. The same zero value might represent the first index of an array, the terminating byte of a string, or the simply result of “2 - 2”. Objective-C constructs an object-oriented layer on top of these primitives, and in so doing establishes a distinct logical universe. This abstraction allows for a sentinel value, the NSNull singleton, to be defined independently of numbers. nil (and Nil) therefore serve as intermediaries between these worlds at their convergence point: zero.

Написано Mattt
Mattt

Mattt (@mattt) is a writer and developer in Portland, Oregon. He is the founder of NSHipster and Flight School, and the creator of several open source libraries, including AFNetworking and Alamofire.

Следующая статья

A recurring theme of this publication has been the importance of a healthy relationship with the compiler. Like any craft, one’s effectiveness as a practitioner is contingent on how they treat their tools. Take good care of them, and they’ll take good care of you.