Assuming our -init method only invokes messages on self, why is it common to check if self != nil if messaging nil has no effect?
Let’s say we have an initializer as follows:
- (id)init
{
self = [super init];
if (self) {
[self doThis];
[self setFoo:@"Bar"];
}
return self;
}
Instead of checking self, we could write:
- (id)init
{
self = [super init];
[self doThis];
[self setFoo:@"Bar"];
return self;
}
Now if for some reason [super init] returns nil, there would be no difference in the outcome of the method as far as I know. Why then do we constantly perform this check?
You can send a message to nil, but you cannot access the instance variables of nil. You’ll get an
EXC_BAD_ACCESSexception.Consider a class that has instance variables:
What happens if
[super init]returns nil in this example? You will try to access thatinstanceVariableoff of a null pointer and you will get an exception.Even if you’re not accessing any instance variables, other things can certainly go wrong if you don’t check for
self == nil. You can easily leakmalloc-allocated memory or file handles, or pass yourself to some method that’s not expecting nil.Other answers claim that you can leak objects if you don’t check for nil. For example:
This won’t leak under ARC, even if
selfis nil. Under manual reference counting (MRC), this example will leak whetherselfis nil or not, because there’s nothing to balance the +1 retain count from[NSObject alloc].The proper way to do it under MRC is this:
or this:
Neither of those will leak, whether
selfis nil or not.If you bypass the setter method, like this, you’ll just crash if
selfis nil: