在Swift中引用回调时防止内存泄漏

注意:这个问题与Swift,闭包,回调和内存泄漏有关……其余的只是出于说明目的。

考虑一下,我们有一个ValueAnimator类,它具有以下初始化程序:

init(durationInSeconds: Int,sampleRate: Int,interpolation: Interpolator,callback: @escaping (Double) -> Void) {
        self.maxIterations = durationInSeconds * sampleRate
        self.timeInterval = 1.0 / Double(sampleRate)
        self.interpolation = interpolation
        self.callback = callback
    }

如您所见,我们传入了一个回调。

现在,从ViewController初始化ValueAnimator时,请考虑以下两种定义回调的方式:

选项一,直接定义回调:

class ViewController: ViewController {

    var valueAnimator: ValueAnimator?

    override func viewDidLoad() {
        valueAnimator = ValueAnimator(durationInSeconds: 2,sampleRate: 2,interpolation: .sineWaveFrom0To1To0)
        { [weak self] value in
            guard let self = self else { return }

            // Do something with value ...
        }
        valueAnimator?.start()
    }

}

选项二,将回调定义为单独的函数并引用它:

(我宁愿采用这种方式……因为我发现,在闭包内的闭包内不存在闭包,这不是“认知负担”)

class ViewController: ViewController {

    var valueAnimator: ValueAnimator?

    override func viewDidLoad() {
        valueAnimator = ValueAnimator(durationInSeconds: 2,interpolation: .sineWaveFrom0To1To0,callback: theCallback)
        valueAnimator?.start()
    }

    func theCallback(value: Double) {

        // Do something with the value ...

    }

}

正如您在第一个版本中看到的那样,有一些针对参考周期的保护措施。

在第二个版本中是否有某种方法可以应用这种相同的保护措施?还是出于某种原因没有必要吗?

谢谢!

liusha7258322 回答:在Swift中引用回调时防止内存泄漏

要将相同的保护应用于第二种方法,请发送self而不是回调,并在您的类ValueAnimator中定义

weak var delegate:ViewController?

然后在响应中做

delegate?.callback(value:<#value#>)
,

您可以选择使用父代委托(自身)调用任何函数。

init(durationInSeconds: Int,sampleRate: Int,interpolation: Interpolator,delegate: 
AnyObject?,callback: @escaping (Double) -> Void) {
    self.maxIterations = durationInSeconds * sampleRate
    self.timeInterval = 1.0 / Double(sampleRate)
    self.interpolation = interpolation
    delegate?.callback(value: 0)
}


class ViewController: ViewController {

var valueAnimator: ValueAnimator?

override func viewDidLoad() {
    valueAnimator = ValueAnimator(durationInSeconds: 2,sampleRate: 2,interpolation: .sineWaveFrom0To1To0,delegate: self,callback: theCallback)
    valueAnimator?.start()
}

func theCallback(value: Double) {

    // Do something with the value ...

}

} 
本文链接:https://www.f2er.com/3047802.html

大家都在问