此外,对 self 的间接引用也会对 self 产生保留。例如,如果_ivar
是一个实例变量,访问它是对 self 的隐式引用,因此以下内容也将保留 self。
^(id sender) {
[_ivar popViewControllerAnimated:YES];
}
此外,为了扩展您的weak
示例,可以向弱引用发送消息。如果它为零,则不会发生任何事情。如果不是,则编译器将生成代码,以确保通过调用方法来确保引用保持有效。
所以,这很好:
__weak Foo *weakSelf = self;
^(id sender) {
[weakSelf.foo doSomething];
}
因为 foo 要么是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
。
因此,在上述最后两种情况下,您希望执行以下操作:
__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 时才会出现问题......