一種のフォローアップとして[[class alloc] init] から nil を返すことは良い習慣と見なされますか? 、あまり議論されていないケースがあります: 次の init を呼び出す前に、いくつかの前提条件に失敗した init をどうするか?
たとえば、この initWithStuff: メソッドで nil が渡されるか、一般に initWithValue: に渡す値がないことは絶対的な失敗であり、確実に nil を返したいとします。
- (id)initWithStuff:(Stuff *)inStuff {
if (!inStuff || ![inStuff hasValidValue])
{
// can't proceed to call initWithValue: because we have no value
// so do what?
return nil;
}
NSInteger value = [inStuff integerValue];
return [super initWithValue:value];
}
おそらくより明確な例は、ラップする指定されたイニシャライザ メソッドがオブジェクト ポインタを取り、nil が渡された場合に例外をスローする場合です。例外を引き起こす init 呼び出しを確実に短絡する必要があります。
私の推測: 可能な限り init してから、nil を返す前に self を解放します。必要に応じて、裸の init またはその他の初期化子を呼び出して、self を解放する前に既知の状態にします。
// can't proceed to call super's initWithValue: because we have no value
// so do what? do this:
self = [super init]; // or initWithValue:0
[self release];
return nil;
そして、有効なデータなしで機能するそのような初期化子がなかった場合、有効なダミーデータを構築する必要があると思います。または、その作成者に文句を言って、それまでは nil を返して、リークに対処してください :^)
また、ARC は状況にどのように影響しますか?
私の推測では、可能な限り init を終了してから、nil を返すだけです。self を設定するのは冗長かもしれないと思うかもしれませんが、場合によってはそうではありません。いずれにせよ、コンパイラの警告を黙らせるためにそこにある必要があります。
// can't proceed to call super's initWithValue: because we have no value
// so do what? do this:
self = [super init]; // finish init so ARC can release it having no strong references
return nil;
私の推測は間違っていますか?