[英]Weak Self in Blocks
我是否需要检查弱自我是否在块中为零?
我创建了weakSelf指针,如:
__weak typeof(self) weakSelf = self;
在我做的块的开头
if(!weakSelf){return;}
这是不必要的吗? 或者它取决于我是否正确编码其余部分,以便当自我死亡时,其他人也会死亡?
这种检查是不必要的,并且给你一种错误的安全感。
这是问题所在:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (!weakSelf) { return; }
// THE LINE OF INTEREST
[weakSelf doSomething];
});
在THE LINE OF INTEREST
,其他一些线程可能会清除对self
的最后一个强引用,此时weakSelf
设置为nil。 所以doSomething
消息被发送到nil,这是“安全的”(它什么都不做),但可能不是你所期望的!
如果你想在weakSelf
为零时采取不同的行动, weakSelf
,例如
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf) {
[weakSelf doSomething];
} else {
[someOtherObject doSomethingElse];
}
});
在这种情况下,在块验证weakSelf
不是nil的时间和发送doSomething
消息的时间之间, weakSelf
可能变为nil,并且doSomething
和doSomethingElse
都不会实际运行。
正确的解决方案是:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomething];
} else {
[someOtherObject doSomethingElse];
}
});
在这种情况下,将weakSelf
复制到strongSelf
(默认情况下很强)是原子的。 如果weakSelf
为零,则strongSelf
将为零。 如果weakSelf
不是nil, strongSelf
将不会是nil,并且将成为对象的强引用,防止它在doSomething
消息之前被释放。
这似乎是非常不必要的,因为在nil上调用消息是一种无操作。 (什么都没发生)
^{
[weakSelf doSomething]; //Does nothing if weakSelf is nil
}
我认为你可能想要这样做的唯一原因是不应该调用其他消息(不是自己的)
^{
// Here I don't want to add weakSelf as an observer if it's nil
if (!weakSelf) return;
[OtherClass addObserverForSomething:weakSelf];
}
弱引用不保留引用的对象。 如果没有其他人保留它,则释放该对象,并且弱引用指的是nil
。
因此,您的代码可能使用引用为nil
的weakSelf
执行。 但这根本没有理由检查它。 特别是在Objective-C中,如果发送消息为nil
,则使用已定义的行为。 I. e。 如果使用nil
引用设置属性,它是完美的代码。 它简直无处可去。
当然有时候你不想与nil
交互。 在这种情况下,你必须检查它。
顺便说一句:你只需要在一些很少的情况下需要weakSelf
。 这是一个城市传说,在封闭中一般提到self
必须弱,以防止保留周期。 它不是真的,它不是真的,它永远不会是真的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.