在 swift 的嵌套块中使用 [weak self]

Use [weak self] in the nested block in swift

我正在努力在 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
                            }
                        }
                    } 
                }
            }
        }
    }
}

我的假设是 sing animate 方法的动画块允许转义,

class func animate(withDuration duration: TimeInterval, 
    animations: @escaping () -> Void, 
    completion: ((Bool) -> Void)? = nil)

我把每个动画块都做了一个weak self,调用动画块的时候不知道self是否还存在。因此,我使用 guard 语句创建了一个 strongSelf 变量。我对每个块都这样做以确保自我的存在,但我应该将它们包含在每个块中,还是不应该?我想知道为什么我需要/不需要积木....

如果你不使用[weak self],那么在那个块的生命周期内,你可以在它和self引用的对象之间有一个循环引用,当一个对象失去对它的引用时,它引用下降一,当它达到零时,它会被释放并减少它引用的任何对象的引用计数。如果您有循环引用,那么两者都不会达到零,因为两者都不会达到零以释放自身并减少对另一个的引用。对于常规对象,这是一个问题,因为它们永远不会被释放,但对于块,它可能取决于它们的使用方式,如果将它们传递给立即使用它们的函数,那么一旦它们被执行,它们就会被释放,并且任何循环引用都将被删除,这甚至可能是有益的,因为当你的块正在执行时它和 self 不能消失,但如果该块被保留为要调用的实例变量,那么你有一个循环引用永远不会消失。处理的方法是使用[weak self],说这个块中对self的引用是弱的,然后你可以在每次使用它时处理它,例如self?.myFunction(),或者你可以一开始就创建一个强引用,以前你必须使用不同的变量给自己,但现在你可以去

guard let self = self else { return }

这样做的好处之一,你是说如果它走到这一步我希望块完全执行,你已经为块的执行创建了一个循环引用并且它不会消失直到块完成执行。例如,如果你有几个以 self? 开头的函数,那么执行 self 的中途可能会变成 nil,只有前几个函数被执行,后面的不执行。