ios - 我应该在嵌套 block 中使用 weakSelf 吗?

标签 ios objective-c objective-c-blocks retain-cycle

我正试图正确地避免在 Objective C 中使用 block 的保留循环,并且不确定是否具有嵌套 block 。

如果我像这样写一个简单的 block :

[self doSomethingWithBlock:^{
    [self doSomethingElse];
}];

编译器捕获并警告我这可能会导致保留循环。我将其更改如下以避免循环:

__weak __typeof(self)weakSelf = self;
[self doSomethingWithBlock:^{
    __strong __typeof(weakSelf)strongSelf = weakSelf;
    [strongSelf doSomethingElse];
}];

当我写这样的东西时:

[self doSomethingWithBlock:^(MyObject* object){
    [object doSomethingElseWithBlock:^{
        [self doYetAnotherThing];
    }];
}];

编译器很高兴,但我不相信它是安全的。即使中间有一个 object,它在概念上看起来仍然和上面一样,但现在它是一个有 3 个 retains 的循环。

应该是这样吗?

[self doSomethingWithBlock:^(MyObject* object){
    __weak __typeof(self)weakSelf = self;
    [object doSomethingElseWithBlock:^{
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        [strongSelf doYetAnotherThing];
    }];
}];

还是这样?

__weak __typeof(self)weakSelf = self;
[self doSomethingWithBlock:^(MyObject* object){
    [object doSomethingElseWithBlock:^{
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        [strongSelf doYetAnotherThing];
    }];
}];

最佳答案

在这种情况下,您不必担心循环引用。您担心的是实际上不再需要对象 self 的情况,但是在嵌套 block 中使用 self 会使它不必要地保持事件状态。例如,如果你有一个 View Controller ,当 View 被屏幕移除时应该消失,但你下载了一张你想在 Controller View 中显示的图像。如果图像在 View 消失后很长时间才到达,那么您不希望 View Controller 再事件。

最好的是

__weak typeof (self) weakSelf = self;

在调用最外层方法之前。然后在每个应该使用 self 的 block 中,添加

typeof (self) strongSelf = weakSelf;

并在该 block 中使用 strongSelf。根据情况,您可能想检查 strongSelf 是否在此时不为 nil,但是当它为 nil 时向 strongSelf 发送消息无效,因此如果您所做的只是发送消息并获取或设置属性,那么检查因为没有必要。

如果不这样做会怎样?不同之处在于,如果您在任何地方(或仅在最里面的 block 中)都使用 self ,那么 self 可能会不必要地保持在最里面的 block 中。

关于ios - 我应该在嵌套 block 中使用 weakSelf 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38835792/

相关文章:

ios - 字体 BebasNeue 不适用于 iOS 11

ios - 如何将数据从表单 FormSeetController 传递到 ViewController?

objective-c - 地幔和核心数据 : Only one Model

ios - 我什么时候应该使用 "performBlock"方法?

pointers - 分配 block 指针: differences between Objective-C vs C++ classes

ios - 如何使用 __block 和完成 block 避免内存泄漏

ios - ARSKView 在关闭 ViewController 时不释放内存

c# - 无法覆盖 UIView.Draw 方法

ios - 单击按钮时的动画 View

objective-c - 控制 Segue 目的地 返回按钮 导航栏