我应该在PromiseKit块中使用[弱自我]吗?

时间:2016-09-01 21:34:24

标签: swift retain-cycle promisekit

PromiseKit在their website上声明了以下内容:

  

我应该关注保留周期吗?

     

tl; dr:在promise处理程序中使用self是安全的。

     

这是安全的:

somePromise.then {
    self.doSomething()
}
     

如果somePromise已解决,则会释放传递给then的函数,因此无需指定[weak self]

     

指定[无主自我]可能很危险。

     

你告诉我不要担心保留周期?!

     

不,只是默认情况下,使用PromiseKit时不会导致保留周期。但它仍有可能......

这是否意味着我永远不应该在PromiseKit块中使用[weak self]?有没有我还需要使用[weak self]的情况?究竟是如何阻止保留周期的?

2 个答案:

答案 0 :(得分:10)

TL; DR:继续在PromiseKit块中使用[weak self],以防止对象长寿超过必要的时间。

有几点需要注意。首先,在一个块中使用[weak self]有两个主要原因:

  1. 防止保留周期
  2. 防止生活时间超过必要的物品
  3. 其次,当您调用该代码块时,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