While using lazy initialisers, is there a chance of having retain cycles?
In a blog post and many other places [unowned self]
is seen
class Person {
var name: String
lazy var personalizedGreeting: String = {
[unowned self] in
return "Hello, \(self.name)!"
}()
init(name: String) {
self.name = name
}
}
I tried this
class Person {
var name: String
lazy var personalizedGreeting: String = {
//[unowned self] in
return "Hello, \(self.name)!"
}()
init(name: String) {
print("person init")
self.name = name
}
deinit {
print("person deinit")
}
}
Used it like this
//...
let person = Person(name: "name")
print(person.personalizedGreeting)
//..
And found that "person deinit" was logged.
So it seems there are no retain cycles. As per my knowledge when a block captures self and when this block is strongly retained by self, there is a retain cycle. This case seems similar to a retain cycle but actually it is not.
I tried this [...]
lazy var personalizedGreeting: String = { return self.name }()
it seems there are no retain cycles
Correct.
The reason is that the immediately applied closure {}()
is considered @noescape
. It does not retain the captured self
.
For reference: Joe Groff's tweet.