OStack程序员社区-中国程序员成长平台

标题: ios - 防止retain-cycle的两种阻塞方式 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 13:41
标题: ios - 防止retain-cycle的两种阻塞方式

如果可能存在保留周期,我通常使用这样的 block :

- (void)someFunction {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
        [weakSelf doSomething];
    }];
}

但最近我看到了另一种方式:

- (void)someFunctionWithParamid)param {
    __weak __typeof(param) weakParam = param;
    [self setHandler:^{
        __typeof(weakParam) strongParam = weakParam;
        [strongParam doSomething];
    }];
}    

它们有什么区别?

Edit1:这是否意味着 self 运行处理程序时 param 不会被释放?



Best Answer-推荐答案


在第二个示例中,在特定情况下创建 strongSelf 变量没有任何好处,但我可以向您展示一个有好处的示例。

在第一个示例中,语句 [weakSelf doSomething] 加载 weakSelf 中的引用,保留它,发送 doSomething 消息,然后然后(在 doSomething 返回之后)释放引用。第二个示例“手动”执行基本完全相同的步骤。

这里有一个稍微不同的例子:

- (void)someFunction {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
        [weakSelf doSomething];
        [weakSelf doAnotherThing];
    }];
}

在我的代码中,假设在调用 block 时只有一个对 self 对象的强引用。 [weakSelf doSomething] 语句创建第二个对它的临时强引用。当 doSomething 运行时,另一个线程释放另一个强引用。当 doSomething 返回时,该语句将释放其临时强引用。现在 self 没有更多的强引用,所以它被释放并且 weakSelf 被设置为 nil。

然后 [weakSelf doAnotherThing] 语句运行。它想加载并保留 weakSelf 的内容,但由于 weakSelf 现在为 nil,该语句只使用 nil。它将 doAnotherThing 消息发送到 nil,这是允许的并且不会崩溃。它什么也不做。它不调用该方法。

这可能不是您想要的行为。如果 doSomething 运行,您可能总是希望 doAnotherThingself 上运行。那是您需要第二个示例中的模式的时候:

- (void)someFunctionWithParamid)param {
    __weak __typeof(self) weakSelf = self;
    [self setHandler:^{
        __typeof(weakSelf) strongSelf = weakSelf;
        [strongSelf doSomething];
        [strongSelf doAnotherThing];
    }];
}    

这里,当 block 被调用时,它会立即在 strongSelf 中存储对 self 的强引用(或者如果 weakSelf 有则存储 nil已经设置为零)。 strongSelf 引用直到最后一次使用 strongSelf 变量后才能释放,因此 self 不可能在 之后被释放>doSomething 但在 doAnotherThing 之前。

关于ios - 防止retain-cycle的两种阻塞方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37825148/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4