Accessing self from instance properties which are closures

This looks interesting, so I dig little deeper. Found that, you can access the class instance variables within the closure like self.instanceVariable. Then the closure will capture the self within it. So now the self refers to the class instance itself. Your closure should be a lazy property.

A lazy property means that you can refer to self within the default closure, because the lazy property will not be accessed until after initialization has been completed and self is known to exist.

You are missing @lazy so that self is unknown to the closure thats why it is printing it as (Function) my guess.

class TableViewController: UIViewController {
var name = "anil"
// Since swift 2.0 came out @lazy is replaced by lazy
lazy  var c1: () -> () = {
    println(self)
    println(self.name)

}

var c2: () -> () {
get {
    return { println(self) }
}
}

var c3: () -> () {
return { println(self) }
}


  override func viewDidLoad() {
        super.viewDidLoad()
        c1()
        c2()
        c3()
        }
}

Output

<_TtC12TableViewApp19TableViewController: 0x10d54e000>
anil
<_TtC12TableViewApp19TableViewController: 0x10d54e000>
<_TtC12TableViewApp19TableViewController: 0x10d54e000>


Update

Assigning closure to a class instance variable results strong reference cycle. You should avoid this. Swift uses Capture list for that

If you assign a closure to a property of a class instance, and the closure captures that instance by referring to the instance or its members, you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles. For more information, see Strong Reference Cycles for Closures.

So the correct usage of closure could be

@lazy  var c1: () -> () = {
    [unowned self] in
    println(self)
    println(self.name)

}

Reference: Swift programming guide

Edit
@lazy has been changed to lazy

Leave a Comment