我正在Swift中调用动画,我对在嵌套块中使用[weak self]
有点困惑。我看到了其他一些与这个问题有关的帖子,但这让我很困惑,因为有些人说他们需要weak self
,有些人不需要。
我的动画块是这样的。
func showFocusView() {
UIView.animate(withDuration: 0.3, delay: 0, options: [.curveEaseInOut]) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.focusView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
strongSelf.focusView.alpha = 1
} completion: { animated in
if !animated {
return
} else {
UIView.animate(withDuration: 0.1, delay: 0, options: [.curveEaseInOut]) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.focusView.transform = .identity
} completion: { animated in
if !animated {
return
} else {
UIView.animate(withDuration: 1.5, delay: 0, options: [.curveEaseInOut]) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.focusView.alpha = 0.5
} completion: { animated in
if !animated {
return
} else {
UIView.animate(withDuration: 0.5, delay: 0, options: [.curveEaseInOut]) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.focusView.alpha = 0
}
}
}
}
}
}
}
}
我的假设是,使用animate方法的动画块可以进行转义,
class func animate(withDuration duration: TimeInterval,
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil)
我让每个动画块都是一个弱自我,当调用动画块时,不确定这个自我是否仍然存在。因此,我使用一个guard语句创建了一个strongSelf变量。我对每个区块都这样做,以确保自我的存在,但我应该把它们包括在每个区块中吗,还是不应该?我想知道为什么我需要/不需要这个块。。。。
如果你不使用[weak self],那么在该块的生命周期内,你可以在它和self引用的对象之间有一个循环引用,当一个对象失去对它的引用时,它的引用会减少一,当它达到零时,它会被释放,并减少它引用的任何对象的引用计数。如果你有一个循环引用,那么两者都不会达到零,因为两者都不会到达零来释放自己并减少对另一个的引用。对于常规对象来说,这是一个问题,因为它们永远不会被释放,但对于块来说,这可能取决于它们的使用方式,如果它们被直接传递给使用它们的函数,那么一旦它们被执行,它们就会被释放,并且任何循环引用都会被剪切,甚至可能有益的是,当你的块正在执行时,但是,如果块被保留为要调用的实例变量,那么您就有了一个永远不会消失的循环引用。处理的方法是使用[弱自我],说在这个块中对自我的引用是弱的,然后你可以在每次使用它时处理它,自我?。例如,myFunction((,或者你可以在一开始创建一个强引用,过去你必须使用不同的变量来self,但现在你可以使用
guard let self = self else { return }
这样做的好处之一是,你说如果它走到这一步,我希望块完全执行,你已经为块的执行创建了一个循环引用,它不会消失,直到块完成执行。例如,如果您有一些以self?开头的函数?,然后在块执行到一半的时候,self可能变成nil,并且只有前几个函数被执行,后面的函数没有被执行。