NOTE: This question has to do with Swift, closures, callbacks, and memory leaks... the rest is for illustration purposes.
Consider we have a class, ValueAnimator, that has the following initializer:
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
}
As you can see we have a callback that is passed in.
Now, consider these two different ways of defining the callback when initializing the ValueAnimator from a ViewController:
Option one, define the callback in-line:
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()
}
}
Option two, define the callback as a separate function and referencing it:
(I would prefer this way of doing it... because I find it is less of a "cognitive load" not to have closures within closures within closures... hence then question)
class ViewController: ViewController {
var valueAnimator: ValueAnimator?
override func viewDidLoad() {
valueAnimator = ValueAnimator(durationInSeconds: 2, sampleRate: 2,
interpolation: .sineWaveFrom0To1To0, callback: theCallback)
valueAnimator?.start()
}
func theCallback(value: Double) {
// Do something with the value ...
}
}
As you can see with the first version, there is some protection against a reference cycle.
Is there some way of applying this same protection in the second version... or is it not necessary for some reason?
Thankyou!
To apply that same proptection to the second way send self
instead of the callback and in your class ValueAnimator
define
weak var delegate:ViewController?
Then inside the response do
delegate?.callback(value:<#value#>)