便利なコンストラクター クラス メソッドを使用する理由は 2 つあります。1 つ目は、のイディオム[[Thing alloc] initWithFoo: xyz]
は非常に一般的ですが、どこでも入力しなければならないのは不便だということです。だから、[Thing thingWithFoo: xzy]
一般的な略語です。
より深い理由は、参照カウントに関係しています。で始まるメソッドinit
は、インスタンスの参照を返すことになっており、その所有権は呼び出し元に譲渡されます。一方、コンビニエンス クラス メソッドは通常autorelease
d 参照を返します。
+ (id)packetWithType:(PacketType)packetType
{
return [[[[self class] alloc] initWithType:packetType] autorelease];
}
これは、ダングリング参照やメモリ リークを回避するために知っておくことが重要です。
Thing* thing = [[Thing alloc] initWithFoo: xyz];
// Now, *I* own the reference and *I* am responsible for releasing
// it, when I no longer need it.
[thing release]
一方、によって返される参照
Thing* thing = [Thing thingWithFoo: xyz];
「最も近い」が所有していNSAutoreleasePool
ます。呼び出し元はそれを解放する責任はありません (実際、それは間違っています!)。参照を保持する場合、呼び出し元は実際retain
にここで参照する必要があります。
self->myMember = [thing retain];
たとえ(ARCの下で)それらに従うコードを生成するのがコンパイラであっても、基礎となる規則は依然として有効であるため、ARCを使用する場合でもこれらの規則について知っておく必要があります。NARC
頭字語は、どのメソッド名のプレフィックスが特定の責任を伴うかを覚えておくのに良い方法です。この回答には詳細があります。