4

機能的に同等のコードがあります:

self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];
self.myProperty = [[MyClass alloc] initWithBla:bla blur:blur];

上に示したように、実際にはこれを 2 回続けて実行しているわけではありませんが、実際に起こっていることです。私の質問は、これにより ARC Objective C でメモリ リークが発生するのでしょうか? self.myProperty最初の呼び出しで割り当てられたメモリはself.myProperty、新しく割り当てられた のインスタンスを指すように再割り当てされる前に再利用されますMyClassか?

4

2 に答える 2

11

プロパティの実装にリー​​クはありません。また、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
于 2012-05-08T06:31:01.920 に答える
2

大丈夫です、ここでメモリリークはありません。それがARCの要点です。

于 2012-05-08T06:18:22.247 に答える