首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >打破强/弱自我的保留周期

打破强/弱自我的保留周期
EN

Stack Overflow用户
提问于 2015-07-08 02:22:57
回答 5查看 3.8K关注 0票数 10

我读过关于强/弱self以打破保留周期的文章,但对于它们是如何工作的,我仍然感到困惑。我理解如何使用__weak typeof(self) weakSelf = self创建对自我的弱引用,但我对强引用感到困惑。据我所知,强引用是指对self的强烈引用,这样它就不会在块结束之前被释放,对吗?那么,为什么有必要拥有__strong typeof(self) strongSelf = weakSelf呢?这不是最终指向了self对象吗?所以为什么不只是strongSelf = self

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-07-08 04:19:19

在创建块时,您在块中引用的任何非弱对象都将导致对该对象的隐式保留。不是执行,而是创建。

如果您直接从自我初始化内部strongSelf,您将保留自我的价值,并可能导致保留周期。

另一方面,如果从weakSelf初始化它,则不会保留weakSelf的值。

这就是这两步的原因。外部代码将self的值复制到weakSelf中,但由于它是__weak(),因此ARC不添加retain。

块"creation“复制weakSelf的值(或者至少在执行时设法使其值可用)。你看不出它是从哪里复制过来的,但它做到了。

在块“执行”时,块将“weakSelf的值”(如果同时自定义为零)复制到strongSelf中,然后将其应用于strongSelf。因此,在块的持续时间内,如果strongSelf引用的对象是活动的,那么它将保持活动状态。如果您只依赖于weakSelf,那么在执行块期间,它可以在任何时候变为零。

请注意,弱/强模式是带带和大括号--许多示例实际上依赖于这样一个事实,即weakSelf将变为零,并且块将悄悄地成为无操作(消息到零)的集合。

只有当(a)在self.property中保留对块的引用,或(b)将块传递给其他对象(通知管理器等),并告诉该其他对象将其遗忘在dealloc中时,才会发生保留循环;在这两种情况下,您的dealloc都不会在块活动时被调用。

当人们说“做这件事的方法是用弱/强模式”时,他们假设的是最坏的情况。

票数 13
EN

Stack Overflow用户

发布于 2015-07-08 03:17:34

其模式是:

代码语言:javascript
运行
复制
__weak typeof(self) weakSelf = self;

[manager someAsynchronousMethodWithCompletionHandler:^{
    typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];

其思想是,完成处理程序块将只具有对self的弱引用,因此如果在调用完成块之前释放self,那么它将安全地被释放,因为该块没有强引用。(一个常见的示例是,当视图控制器启动一些异步网络请求来更新视图时,如果视图控制器在网络请求完成之前被取消,则没有必要为一个早已消失的视图而挂起视图控制器实例。)

但是,这种weakSelf/strongSelf模式还确保,如果相反的情况发生,完成块已经启动,并且在self发布之前遇到了strongSelf行,则块将确保在运行该块的过程中保留self (也就是说,即使在不同的线程上运行,它也不能在运行完成块的过程中得到释放)。这有许多潜在的好处(从对象完整性到消除种族条件)。有时,您实际上不需要strongSelf一半的"weakSelf/strongSelf舞蹈“,但它是一个宝贵的工具,当需要时。

但是,如果在块中有一条线表示,typeof(self) strongSelf = self (而不是weakSelf),那么在声明的右侧仅仅存在self就会导致块在前面保持对self的强烈引用,这完全违背了最初使用weakSelf的目的。

票数 13
EN

Stack Overflow用户

发布于 2015-07-08 04:59:58

有正确的答案,但我真的不知道,它们是否是你Q的答案--它们解释了一般使用self的块保留循环的问题,但你的Q是:

那么为什么不只是strongSelf = self呢?

对这个问题的回答是:

如果要这样做,self将是块闭包的一部分,并且始终保留。自我虚弱的整个故事将是毫无意义的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31282476

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档