Explicit use of self in closures


#1

Outside of closures, we can write things like:

and Swift infers self before the property name:

But inside closures, we have to explicitly write self:

UIView.animateWithDuration(1.0, animations: { self.nextQuestionLabel.alpha = 1.0 self.currentQuestionLabel.alpha = 0.0 })

As far as I have been able to discover, Swift makes you explicitly write self inside a closure in order to warn you that the closure is going to “capture” self. Capturing variables is what closures do, and explicitly writing self doesn’t change anything. self would be captured by the closure in either case: using self implicitly or writing self explicitly–it’s just that making you write self explicitly serves as a visible reminder that self is being captured. If you were naive and didn’t realize that Swift infers self implicitly when your code refers to methods or properties of the ViewController, and then you looked inside the closure and didn’t see self anywhere, you might mistakenly believe that self is not being captured.

Why does Swift consider it so important that you be made aware that self is being captured by a closure? To help you avoid memory leaks, which is something the book hasn’t talked about yet.

If you know any Objective-C, the retain count of the ViewController instance increases by 1 when you refer to any of the ViewController’s properties or methods inside a closure. There are declarations that you can make to prevent the retain count from increasing, but the default is for the retain count to increase when you use self inside a closure.


#2

Thank you for the good explanation, I was just about to post a question about the explicit use of self in the animation closure.


#3

Correct! That’s why closures feature “capture list” to help avoid retain cycle.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID56