The [weak self]
in anotherFunctionWithTrailingClosure
is not needed.
You can empirically test this:
class Experiment {
func someFunctionWithTrailingClosure(closure: @escaping () -> Void) {
print("starting", #function)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
closure()
print("finishing", #function)
}
}
func anotherFunctionWithTrailingClosure(closure: @escaping () -> Void) {
print("starting", #function)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
closure()
print("finishing", #function)
}
}
func doSomething() {
print(#function)
}
func testCompletionHandlers() {
someFunctionWithTrailingClosure { [weak self] in
self?.anotherFunctionWithTrailingClosure { // [weak self] in
self?.doSomething()
}
}
}
// go ahead and add `deinit`, so I can see when this is deallocated
deinit {
print("deinit")
}
}
And then:
func performExperiment() {
DispatchQueue.global().async {
let obj = Experiment()
obj.testCompletionHandlers()
// sleep long enough for `anotherFunctionWithTrailingClosure` to start, but not yet call its completion handler
Thread.sleep(forTimeInterval: 1.5)
}
}
If you do this, you will see that doSomething
is never called and that deinit
is called before anotherFunctionWithTrailingClosure
calls its closure.
That having been said, I might still be inclined to use the [weak self]
syntax on anotherFunctionWithTrailingClosure
to make my intent explicit.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…