プロパティの実装にリークはありません。また、ARCを使用している限り、プロパティに割り当てる場所にもリークはありません。
呼び出し:
self.myProperty = something
次のような生成されたアクセサーを呼び出します(_myProperty
プロパティのバッキングivarであると想定)。
- (void)setMyProperty:(MyClass *)anInstance
{
if (_myProperty == anInstance)
return;
[_myProperty release];
_myProperty = [anInstance retain];
}
以前プロパティが保持していたオブジェクトが解放されるため、ここでリークすることはありません。また、ARCを使用している場合、コンパイラによって生成されたコードは同じように機能します。
リークの可能性に注意するのは正しいですが、(私が知る限りでは)どこに疑わしいのかはわかりません。
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
これにより、保持カウントが+1の新しいオブジェクトが作成され、プロパティに割り当てられます(その後、再び保持されます:+2)。したがって、ここのコードには、そのオブジェクトへの所有権参照がまだあります。その行を繰り返すと、まだ所有している最初の参照が孤立します。ARCを使用している場合は、問題ありません。オブジェクトが確実に解放されます。そうでない場合でも、その孤立したオブジェクトは保持されます。実際にリークが発生します。ARC以外で行うべき適切なことは、次のとおりです。
self.myProperty = [[[MyClass alloc] initWithBla:bla blur:blur] autorelease];
しかし、繰り返しになりますが、ARCを使用すれば問題ありません。
コメントからの関連する質問に対処するには:これはまだ問題ありませんが、ARCではなくローカル変数に割り当てる場合に限りますself.myProperty
。あなたが書くとき:
id myLocalVar;
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
コンパイラはそれを次のように変換します。
__strong id myLocalVar; // variables are strong by default
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
[myLocalVar release]; // ARC inserts release before myLocalVar is reassigned to another object
myLocalVar = [[MyClass alloc] initWithBla:bla blur:blur];
// ... sometime later ...
[myLocalVar release]; // ARC inserts another release when myLocalVar goes out of scope