また、self への間接参照も、self に保持を作成します。たとえば_ivar
、インスタンス変数の場合、それにアクセスすると、self への暗黙的な参照になるため、次の例でも self が保持されます。
^(id sender) {
[_ivar popViewControllerAnimated:YES];
}
さらに、あなたの例を拡張するためweak
に、弱参照にメッセージを送信しても問題ありません。nil の場合、何も起こりません。そうでない場合、コンパイラは、メソッドの呼び出しによって参照が有効なままであることを保証するコードを生成します。
したがって、これで問題ありません。
__weak Foo *weakSelf = self;
^(id sender) {
[weakSelf.foo doSomething];
}
foo は になるかnil
、そうでないかのいずれかになるため、 の実行中ずっと非 nil のままであることが保証されますdoSomething
。
ただし、次の呼び出しは、中間呼び出しになる可能性があるため、お勧めself
できませんnil
。これは、おそらく必要なものではありません。
__weak Foo *weakSelf = self;
^(id sender) {
[weakSelf.foo doSomething];
[weakSelf.foo doSomethingElse];
}
その場合、おそらくブロック内に独自の強い参照を作成して、ブロックの実行全体で一貫した値を保持する必要があります。
一方、弱い参照を介して iVar に直接アクセスする場合は、次のコードが原因で、弱い強いダンスを行う必要があります。
__weak Foo *weakSelf = self;
^(id sender) {
weakSelf->_foo = bar;
}
あれば爆破しweakSelf
ますnil
。
したがって、上記の最後の 2 つの状況では、次のようなことを行います。
__weak Foo *weakSelf = self;
^(id sender) {
Foo *strongSelf = weakSelf;
if (!strongSelf) return;
// Now, do anything with strongSelf, as it is guaranteed to be around
}
もちろん、iVar の状況は、実際に iVar に直接アクセスする場合にのみ問題になります...