繁体   English   中英

块中的弱自我

[英]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,并且doSomethingdoSomethingElse都不会实际运行。

正确的解决方案是:

__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

因此,您的代码可能使用引用为nilweakSelf执行。 但这根本没有理由检查它。 特别是在Objective-C中,如果发送消息为nil ,则使用已定义的行为。 I. e。 如果使用nil引用设置属性,它是完美的代码。 它简直无处可去。

当然有时候你不想与nil交互。 在这种情况下,你必须检查它。

顺便说一句:你只需要在一些很少的情况下需要weakSelf 这是一个城市传说,在封闭中一般提到self必须弱,以防止保留周期。 它不是真的,它不是真的,它永远不会是真的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM