楽器の使用に敬意を表します。
まず、init/dealloc で iVar を直接使用する必要があります。
次に、自分で合成しますか、それともセッターを自分で実装しますか?
また、デバッグまたはリリース用に最適化されたコードを実行していますか?
さて、なぜ私があなたの質問にもっと質問をして答えたのかを説明します。
自分で合成する場合 (つまり、独自のインスタンス変数を宣言する場合は、それも __weak として宣言する必要があります。コンパイラに任せると、適切に処理されます。
さて、あなたは明らかに ARC を使用しています。そのため、コンパイラは手動で参照カウントを実行するコードを自動的に追加します (一部は後でオプティマイザによって削除される可能性があります)。さて、私はコンパイラが自動的に作成するものについて専門家のふりをしているわけではありませんが、以下に非常に近いものになるでしょう.
たとえば、基本的な課題を考えてみましょう...
- (void)setContainer(Container*)container {
_container = container;
}
コンパイラが ARC コードの挿入を完了すると、これは次のようになります (_container が __weak と宣言されていないと仮定すると)...
// Converted by ARC -- so it's MRC
- (void)setContainer(Container*)container {
[container retain];
Container *oldContainer = _container;
_container = [container retain];
[oldContainer release];
[container release];
}
_container が __weak であると仮定すると、次のようになります...
- (void)setContainer(Container*)container {
[container retain]
Container *oldContainer = [_container retain];
objc_storeWeak(&_container, container);
[oldContainer release];
[container release];
}
ここで、objc_storeStrong は強力な変数に割り当てるためのシーケンスであるため、上記のコードのどこに収まるかは明らかです。
また、コンパイラはコードを追加する方法について非常に慎重であることに注意してください。オプティマイザーは非常に積極的で、明らかに不要な保持/解放のペアをほとんど削除できます。そのため、ほとんどの場合、デバッグをビルドするかリリースをビルドするかによって、関数の保持/解放のセマンティクスが異なります。
ただし、一般的には、__unsafe_unretained として指定されていない限り、任意のパラメーターで少なくとも保持を取得する必要があります。