You can send a message to nil, but you cannot access nil instance variables. You will get an EXC_BAD_ACCESS exception.
Consider a class with instance variables:
@implementation MyObject { int instanceVariable; } - (id)init { self = [super init]; instanceVariable = 7; return self; }
What happens if [super init] returns nil in this example? You will try to access this instanceVariable value of a null pointer, and you will get an exception.
Even if you do not get access to any instance variables, other things may go wrong if you do not check self == nil . You can easily test malloc allocated memory or file descriptors, or pass yourself to some method that does not expect a null value.
Other answers claim that you can leak objects if you don't check for null. For instance:
@implementation MyObject @synthesize someProperty; // assume it an NSObject * - (id)init { self = [super init]; [self setSomeProperty:[[NSObject alloc] init]]; return self; }
This will not occur under ARC, even if self is zero. In manual reference counting (MRC), this example will flow if self is zero or not, because there is nothing to balance the saving score of +1 from [NSObject alloc] .
The correct way to do this in MRC is:
- (id)init { self = [super init]; [self setSomeProperty:[[[NSObject alloc] init] autorelease]]; }
or that:
- (id)init { self = [super init]; NSObject *object = [[NSObject alloc] init]; [self setSomeProperty:object]; [object release]; return self; }
None of them will leak out, regardless of whether it is self or not.
If you bypass the setter method, like this, you just crash if self is nil:
- (id)init { self = [super init]; _someProperty = [[NSObject alloc] init]; return self; }