forked from NSHipster/articles
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
--- | ||
layout: post | ||
title: "nil / Nil / NULL / NSNull" | ||
|
||
ref: "https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/NumbersandValues/Articles/Null.html" | ||
published: true | ||
--- | ||
|
||
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 existential 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 several different varieties of _nothing_. The reason for this goes back to [a common NSHipster refrain](http://nshipster.com/ns_enum-ns_options/), of how Objective-C bridges the procedural paradigm of C with Smalltalk-inspired object-oriented paradigm. | ||
|
||
C represents _nothing_ as `0` for primitive values, and `NULL` for pointers ([which is equivalent to `0` in a pointer context](http://c-faq.com/null/nullor0.html)). | ||
|
||
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 to one another. | ||
|
||
On the framework level, Foundation defines `NSNull`, which defines a class method, `+null`, which returns the singleton `NSNull` object. `NSNull` is different from `nil` or `NULL`, in that it is an actual object, rather than a zero value. | ||
|
||
Additionally, in [Foundation/NSObjCRuntime.h](https://gist.github.com/4469665), `Nil` is defined 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. | ||
|
||
## There's Something About `nil` | ||
|
||
Newly-`alloc`'d `NSObject`s start life with [their contents set to `0`](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html). This means that all pointers that object has to other objects begin as `nil`, so it's unnecessary to, for instance, set `self.(association) = nil` in `init` methods. | ||
|
||
Perhaps the most notable behavior of `nil`, though, is that it can have messages sent to it. | ||
|
||
In other languages, like C++, this would crash your program, but in Objective-C, invoking a method on `nil` returns a zero value. This greatly simplifies expressions, 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"]) { ... } | ||
|
||
Being aware of how `nil` works in Objective-C allows this convenience to be a feature, and not a lurking bug in your application. Make sure to guard against cases where `nil` values are unwanted, either by checking and returning early to fail silently, or adding a `NSParameterAssert` to throw an exception. | ||
|
||
## `NSNull`: Something for Nothing | ||
|
||
`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][1] the `NULL` or `nil` value so that it can be used in collections: | ||
|
||
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionary]; | ||
|
||
mutableDictionary[@"someKey"] = nil; // Removes value for `someKey` | ||
NSLog(@"Keys: %@", [mutableDictionary allKeys]); // @[] | ||
|
||
mutableDictionary[@"someKey"] = [NSNull null]; // Sets value of NSNull singleton for `someKey` | ||
NSLog(@"Keys: %@", [mutableDictionary allKeys]); // @[@"someKey"] | ||
|
||
--- | ||
|
||
So to recap, here are the four values representing _nothing_ that every Objective-C programmer should know about: | ||
|
||
<table> | ||
<thead> | ||
<tr> | ||
<th>Symbol</th> | ||
<th>Value</th> | ||
<th>Meaning</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td><tt>NULL</tt></td> | ||
<td><tt>(void *)0</tt></td> | ||
<td>literal null value for C pointers</td> | ||
</tr> | ||
<tr> | ||
<td><tt>nil</tt></td> | ||
<td><tt>(id)0</tt></td> | ||
<td>literal null value for Objective-C objects</td> | ||
</tr> | ||
<tr> | ||
<td><tt>Nil</tt></td> | ||
<td><tt>(Class)0</tt></td> | ||
<td>literal null value for Objective-C classes</td> | ||
</tr> | ||
<tr> | ||
<td><tt>NSNull</tt></td> | ||
<td><tt>[NSNull null]</tt></td> | ||
<td>singleton object used to represent null</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
|
||
[1]: http://en.wikipedia.org/wiki/Object_type_(object-oriented_programming)#Boxing |