self in a Swift Self-executing Anonymous Closure
Conclusion:
self
was justnil
the whole time! What a goofy mistake! […] However, that was not the case. Specifically,self
was notnil
. Not only that, butself
wasn’t theself
I expected.[…]
Second, why is
self
an instance of(MyTableCell) -> () -> MyTableCell
and not() -> UIButton
?[…]
If you declare
button
aslazy var
instead oflet
, then the expected behavior occurs. That is,self
is an instance ofMyTableCell
within the self-executing anonymous closure and the call toaddTarget(_:, action:, for:)
works.[…]
The type of
self
resolving to(MyTableCell) -> () -> MyTableCell
is the unfortunate result of theNSObject
instance method-[NSObject self]
and Swift’s curried functions.[…]
Correcting the expression
self
(without backticks) to reference the enclosing type introduces another interesting question: what should be order of operations during initialization? When usinglet
, the property is initialized before the enclosing type. When usinglazy var
, the property is initialized after the enclosing type. I am not a compiler expert, so I will not attempt to answer which is better. But if initialization order cannot be changed in the compiler to fix this, then I think the expected behavior would be to produce the same error as non-NSObject
classes: “Cannot find ‘self’ in scope”.
Previously:
- Using Lazy Variables to Work Around Swift Initialization Rules
- Swift init()
- Strange Tales of Swift Initialization