块中的弱自我 [英] Weak Self in Blocks
问题描述
我是否需要检查弱自我在块中是否为零?
Do I need to check if weak self is nil in blocks?
我创建了weakSelf指针,如:
I create weakSelf pointer like:
__weak typeof(self) weakSelf = self;
在块的开头我做
if(!weakSelf){return;}
这是不必要的吗?或者它取决于我是否正确编码了其余部分,以便当自我死亡时,其他人也会死亡?
is this unnecessary? or does it depend on whether I coded the rest correctly so that when the self dies, others die too?
推荐答案
该检查是不必要的,并给你一种虚假的安全感。
That check is unnecessary, and is giving you a false sense of security.
这就是问题所在:
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (!weakSelf) { return; }
// THE LINE OF INTEREST
[weakSelf doSomething];
});
利息线
,其他一些线程可能会清除对 self
的最后一个强引用,此时 weakSelf
设置为nil。所以 doSomething
消息被发送到nil,这是安全的(它什么都不做),但可能不是你所期望的!
At THE LINE OF INTEREST
, some other thread might clear the last strong reference to self
, at which point weakSelf
is set to nil. So the doSomething
message gets sent to nil, which is "safe" (it does nothing), but might not be what you expected!
如果你想在 weakSelf
为零时采取不同的行动,那就更糟了,例如
It's worse if you want to take a different action when weakSelf
is nil, e.g.
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf) {
[weakSelf doSomething];
} else {
[someOtherObject doSomethingElse];
}
});
在这种情况下,在块验证 weakSelf $之间c $ c>不是nil,它发送
doSomething
消息的时间, weakSelf
可能会变为nil,而且 doSomething
也不会 doSomethingElse
实际上会运行。
In this case, between the time the block verifies that weakSelf
is not nil and the time it sends the doSomething
message, weakSelf
might become nil, and neither doSomething
nor doSomethingElse
will actually run.
正确的解决方案是这样:
The correct solution is this:
__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
消息之前被解除分配。
In this case, copying weakSelf
to strongSelf
(which is strong by default) is atomic. If weakSelf
was nil, strongSelf
will be nil. If weakSelf
was not nil, strongSelf
will not be nil, and will be a strong reference to the object, preventing it from being deallocated before the doSomething
message.
这篇关于块中的弱自我的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!