UIView.animate() :我需要在动画块中对 self 进行弱引用吗? [复制]

Posted

技术标签:

【中文标题】UIView.animate() :我需要在动画块中对 self 进行弱引用吗? [复制]【英文标题】:UIView.animate() : do I need a weak reference to self in the animation block? [duplicate] 【发布时间】:2020-06-16 12:19:38 【问题描述】:

经过一些研究,我发现我的应用程序使用了太多的能量,因为整个应用程序中有几个 UIView 动画,我在完成块中捕获了相关的 UIViewController,而没有对其进行弱引用。

所以实际上,我改变了这个:

func animate() 
    UIView.animate(withDuration: 0.3, animations: 
        self.label.alpha = 0.5
    )  _ in 
        self.animate()
    

进入这个:

func animate() 
    UIView.animate(withDuration: 0.3, animations: 
        self.label.alpha = 0.5
    )  [weak self] _ in 
        self?.animate()
    

但是,我想知道是否需要对 animation 块(self.label.alpha = 0.5 之一)执行相同的操作?

感谢您的帮助

【问题讨论】:

这里的答案具有误导性。见here 【参考方案1】:

不,在这种情况下不需要。动画和完成不会被 self 保留,因此不存在强保留周期的风险。

与Is it necessary to use [unowned self] in closures of UIView.animateWithDuration(...)?重复

【讨论】:

【参考方案2】:

你不需要在静态函数UIView.animate()中使用[weak self]你需要使用weak当retain cycle是可能的并且动画块不是自己保留时。

在媒体上有一个article[weak self] 可能需要也可能不需要

更多信息:

Automatic Reference Counting

Closures

能源问题可能还有另一个问题。

【讨论】:

这与static 无关。这是关于所有权。见here【参考方案3】:

当然,您确实需要在此处使用“弱自我”概念。

事实上请注意:在这种情况下确实非常常见 VC 在动画期间被丢弃......所以确实,这是你“最需要”使用弱点的地方之一-自己的想法。在动画中忘记这一点是项目中很常见的错误。

顺便说一句,当你需要弱自我时,这里有一个方便的语法:

func animate() 
    UIView.animate(withDuration: 0.3, animations:  [weak self] in
        guard let self = self else  return print("gotchya!") 
        self.label.alpha = 0.5
    )  [weak self] in
        guard let self = self else  return print("gotchya!") 
        self.animate()
    

添加这一行..

        guard let self = self else  return 

.. 可能看起来有点啰嗦,但这意味着你不需要“?” 每次在长块中使用“self”之后。

通常你会在这样的块中使用很多“self ...”,并且只使用“let self = self”成语似乎更一致。

因此,即使代码块中只有一行代码(如您的两个示例中所示),这也是一种在任何地方都绝对一致并保持简单的好方法。

请注意,只要您有 return ,您只需添加一个打印语句,以便了解开发过程中发生的情况..

....  [weak self] in
  guard let self = self else  return print("I avoided a crash, woot!") 

....  [weak self] in
  guard let self = self else  return print("logical disaster near line 66") 

您不必这样做,“ return ”就可以了。这只是为了您的方便。

这到底是什么“自我 = 自我”的生意?

如果您发现“self = self”成语令人困惑......老实说,别担心。总是使用那个成语。这真的只是随处可见的“标准”东西。

始终在您的代码库中保持简单的一致性!

更弱的自我奥秘......

这是来自一位英俊的列表成员的有趣 QA:Where does the weak self go?

后来有这种混乱需要担心:What is the difference between a weak reference and an unowned reference?

【讨论】:

非常感谢您的帮助! 这个答案是当前接受的答案有点令人困惑。据我了解,在这种情况下,不需要weak self 来防止保留循环,这是最初的问题。但是,它可以用作控制流的一种手段。 我知道你的意思 @hoshy ,正如我的回答或这里的 ***.com/a/39251222/294884 所解释的那样,你需要“在实践中”,因为你永远不想在动画播放时保留消失的视图。这么说吧——在你工作的任何团队中,如果你忘记了,团队负责人只会将它添加到提交中:) 这是你“必须做的”。 顺便说一句,您是否有任何参考指南确认guard let self = self else return 比在闭包内使用self?. 更好?在公关期间就这件事与一位同事发生了争执。我的观点是,如果不再有self,最好立即离开闭包,而不是在里面执行随机的逻辑,但我想要一些额外的调味汁:) 这个答案其实是!首先,animations 闭包将立即运行,并且不会在动画期间存储。我猜UIKit 会运行它来确定最终状态,然后丢弃它。其次,completion 闭包将立即调用,因为“VC 在动画期间被丢弃”,finished 参数将是false。所以两个闭包都不需要[weak self]。此外,如果您想在 completion 中使用 [weak self] 来“如果 VC 被丢弃,则不运行代码”,您可以使用 !finished【参考方案4】:

什么意思:

我的应用消耗了太多能量

我看不出在视图控制器上保留weak 引用与节能之间有任何直接关系。 捕获self 而不增加其在闭包中的保留计数(这就是我们对对象的弱引用的意思)意味着如果您的视图控制器上不存在其他强引用,那么您的视图控制器将被更快地释放。也许你会在很短的时间内节省一些内存。

我建议去其他地方调查一下,找出你的“精力”问题来自哪里。

关于weak关键字使用的文章很多。

https://medium.com/flawless-app-stories/you-dont-always-need-weak-self-a778bec505ef

【讨论】:

嗨 lucien - 这很明显。因为 OP 忘记了弱自我,他将构建越来越多的视图控制器。可能有 100 个。

以上是关于UIView.animate() :我需要在动画块中对 self 进行弱引用吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

UIView,动画,完成块,UIAlertView

当使用 UIView.animate 动画视图时,其他视图也不需要动画

NSLayoutConstraint 不使用 UIView.animate 进行动画处理

动画没有停止使用 UIView.animate

UIView.animate() 无法为视图设置动画的各种原因都有哪些?

带有 allowUserInteraction 的 UIView.animate 仅在动画的最后一帧中启用 UIButton