nilにメッセージを送信することはできますが、nilのインスタンス変数にアクセスすることはできません。EXC_BAD_ACCESS例外が発生します。
インスタンス変数を持つクラスを考えてみましょう。
@implementation MyObject {
int instanceVariable;
}
- (id)init {
self = [super init];
instanceVariable = 7;
return self;
}
[super init]この例でnilを返すとどうなりますか?instanceVariablenullポインタからアクセスしようとすると、例外が発生します。
インスタンス変数にアクセスしていない場合でも、をチェックしないと、他のことが確実にうまくいかない可能性がありますself == nil。割り当てられたメモリまたはファイルハンドルを簡単にリークmallocしたり、nilを予期していないメソッドに自分自身を渡したりすることができます。
他の回答では、nilをチェックしないと、オブジェクトがリークする可能性があると主張しています。例えば:
@implementation MyObject
@synthesize someProperty; // assume it's an NSObject *
- (id)init {
self = [super init];
[self setSomeProperty:[[NSObject alloc] init]];
return self;
}
これは、たとえselfゼロであっても、ARCではリークしません。手動参照カウント(MRC)ではself、+ 1保持カウントのバランスを取るものがないため、この例はnilであるかどうかに関係なくリークし[NSObject alloc]ます。
MRCでそれを行う適切な方法は次のとおりです。
- (id)init {
self = [super init];
[self setSomeProperty:[[[NSObject alloc] init] autorelease]];
}
またはこれ:
- (id)init {
self = [super init];
NSObject *object = [[NSObject alloc] init];
[self setSomeProperty:object];
[object release];
return self;
}
selfゼロであるかどうかにかかわらず、どちらもリークしません。
このようにsetterメソッドをバイパスすると、isnilの場合にクラッシュしますself。
- (id)init {
self = [super init];
_someProperty = [[NSObject alloc] init];
return self;
}