PromiseKit在their website上声明了以下内容:
我应该关注保留周期吗?
tl; dr:在promise处理程序中使用self是安全的。
这是安全的:
somePromise.then { self.doSomething() }
如果
somePromise
已解决,则会释放传递给then
的函数,因此无需指定[weak self]
。指定[无主自我]可能很危险。
你告诉我不要担心保留周期?!
不,只是默认情况下,使用PromiseKit时不会导致保留周期。但它仍有可能......
这是否意味着我永远不应该在PromiseKit块中使用[weak self]
?有没有我还需要使用[weak self]
的情况?究竟是如何阻止保留周期的?
答案 0 :(得分:10)
TL; DR:继续在PromiseKit块中使用[weak self]
,以防止对象长寿超过必要的时间。
有几点需要注意。首先,在一个块中使用[weak self]
有两个主要原因:
其次,当您调用该代码块时,PromiseKit 创建一个保留周期。 self
通常somePromise
,而somePromise
正在抓住self
。他们说不应该关注这个保留周期的原因是因为保留周期将被PromiseKit自动破坏。释放then
后,somePromise
将不再保留self
,从而打破保留周期。
所以我们知道我们不需要担心PromiseKit块的问题#1,但问题#2呢?
想象一下,视图控制器会触发网络请求承诺,并且在此承诺得到解决之前需要30秒。在解决之前,用户按下后退按钮。通常情况下,UIKit将取消分配视图控制器,因为它不再在屏幕上,系统可以节省资源。但是,由于您在promise中引用了self
,因此无法再释放它。这意味着视图控制器在内存中的存活时间将超过必要时间。
解决问题#2的唯一方法是在块内使用[weak self]
。
注意:有人可能会争辩说,当您的视图控制器退出时,您应该取消正在进行的保证,以便它释放self
上的保留。但是,确定何时应取消分配视图控制器是not a simple task。让UIKit为您处理逻辑要容易得多,如果您确实需要在取消分配视图控制器时执行任何操作,请在视图控制器的dealloc
方法中实现它。如果块强烈地保持在视图控制器上,则无效。
更新:看起来像one of the authors did talk about this,并澄清了提出这些建议的原因:
事实上,保留
self
可能就是您想要的,以便在解除分配self
之前允许解析。
答案 1 :(得分:9)
该文档仅表示您不必担心PromiseKit引入“强引用周期”(以前称为“保留周期”),因为当履行承诺并且块完成运行时,这些强引用会自动生成为你解决了。强弱参考的选择完全取决于你。
例如,如果您只是更新不再存在的场景上的UI元素,则无需对被解除的视图控制器保留强引用。您在该方案中使用weak
。但有时您需要强引用(例如,您可能希望更新基础模型以反映承诺的成功或失败)。
最重要的是,他们所说的是你不应该让PromiseKit决定强大与弱的参考,而应该由你的应用程序更广泛的设计要求驱动。 PromiseKit唯一的硬性规则是你应该避免使用unowned
。