Ios 块中的弱自组织

Ios 块中的弱自组织,ios,objective-c,weak-references,weak-ptr,Ios,Objective C,Weak References,Weak Ptr,我是否需要检查块中的弱self是否为零 我创建弱自我指针,如下所示: __weak typeof(self) weakSelf = self; 在开始的时候,我做了 if(!weakSelf){return;} 这是没有必要的吗?或者,这取决于我是否正确地编码了其余部分,以便在自我消亡时,其他人也会消亡?这似乎是不必要的,因为在nil上调用消息是不可操作的。(什么也没有发生) 我认为您可能想这样做的唯一原因是不应该调用其他消息(不是在self上) ^{ // Here I don't

我是否需要检查块中的弱self是否为零

我创建弱自我指针,如下所示:

__weak typeof(self) weakSelf = self;
在开始的时候,我做了

if(!weakSelf){return;}

这是没有必要的吗?或者,这取决于我是否正确地编码了其余部分,以便在自我消亡时,其他人也会消亡?

这似乎是不必要的,因为在nil上调用消息是不可操作的。(什么也没有发生)

我认为您可能想这样做的唯一原因是不应该调用其他消息(不是在self上)

^{
    // Here I don't want to add weakSelf as an observer if it's nil
    if (!weakSelf) return;

    [OtherClass addObserverForSomething:weakSelf];
}

这种检查是不必要的,给你一种虚假的安全感

问题是:

__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,这是“安全的”(它什么也不做),但可能不是您所期望的

weakSelf
为nil时,如果您想采取不同的操作,情况会更糟,例如

__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
(默认为strong)是原子的。如果
strongSelf
为零,
strongSelf
将为零。如果
strongSelf
不是nil,
strongSelf
将不是nil,并且将是对对象的强引用,防止在
doSomething
消息之前将其释放。

弱引用不会保留引用的对象。如果没有其他人保留它,则对象被释放,弱引用引用引用为
nil

因此,您的代码可能是使用引用了
nil
weakSelf
执行的。但这根本不是检查它的理由。特别是在Objective-C中,如果发送消息
nil
,则使用定义的行为。即。如果您使用
nil
引用设置属性,这是一个完美的代码。它根本就没有用

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


顺便说一句:只有在某些情况下,你才需要
weakSelf
。这是一个城市的传说,在闭包中,通常提及的
self
必须很弱,以防止循环。它不是真的,它不是真的,它永远不会是真的。

这取决于你的区块应该做什么。通常,如果要确保仅在wealSelf不是nil时执行块,则需要该行!基本上,在Obj-C中,任何方法调用都是
nil
指针上的有效操作数,因此无需检查;例如,如果
weakself
nil
,则该方法调用不会在块中引起任何问题:
[weakself doSomething]。在您的代码中,可以简单地使用
self
而不是
weakSelf
。如果直接在块中使用
self
,则块会强烈捕获
self
,使其保持活动状态。如果使用
weakSelf
,则块不会强烈捕获
self
,并允许在块运行之前释放它。这是正确的。因此,物体的寿命更长。只要块需要执行。通常这正是你想要的,但有时不是。“简单地使用
self
而不是
weakSelf
”的建议需要限定:有时它会改变程序的行为。此外,在块无限期保存的情况下,它可以创建一个保留循环。这不会发生在我的答案的代码中,但是一些常用的API(如
NSNotificationCenter
)会无限期地保存块。Erapb没有显示他创建块的上下文。他的用例可能需要避免一个保留周期。我并没有毫无保留地说:“简单地使用
self
而不是
weakSelf
”我说:“在你的代码中,你可以简单地使用self而不是weakSelf”。所以,并没有理由去寻找一些不属于讨论主题的例子。
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf doSomething];
    } else {
        [someOtherObject doSomethingElse];
    }
});