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.animate 动画视图时,其他视图也不需要动画
NSLayoutConstraint 不使用 UIView.animate 进行动画处理
UIView.animate() 无法为视图设置动画的各种原因都有哪些?
带有 allowUserInteraction 的 UIView.animate 仅在动画的最后一帧中启用 UIButton