In this case, you do not need a capture list, because the self link is not mentioned after the personalizedGreeting instance.
As MartinR writes in his comment, you can easily test your hypothesis by registering that the Person object is uninitialized or not when you delete the capture list.
eg.
class Person { var name: String lazy var personalizedGreeting: String = { _ in return "Hello, \(self.name)!" }() init(name: String) { self.name = name } deinit { print("deinitialized!") } } func foo() { let p = Person(name: "Foo") print(p.personalizedGreeting)
Obviously, in this case there is no risk of a strong reference cycle and, therefore, there is no need for an unowned self capture list in lazy closure. The reason for this is that lazy closure is done only once and uses only the return value of the closure (lazy), creating an instance of personalizedGreeting , while the reference to self in this case does not complete the closure.
If we kept a similar closure in the property of the Person class, we would create a strong reference loop, since the self property will retain a strong reference to self . For example:.
class Person { var name: String var personalizedGreeting: (() -> String)? init(name: String) { self.name = name personalizedGreeting = { () -> String in return "Hello, \(self.name)!" } } deinit { print("deinitialized!") } } func foo() { let p = Person(name: "Foo") } foo()
Hypothesis: lazy instantiations automatically unowned self as weak (or unowned ) by default
As we examine the following example, we understand that this hypothesis is false.
class Bar { var foo: Foo? = nil } class Foo { let bar = Bar() lazy var dummy: String = { _ in print("executed") self.bar.foo = self return "dummy" }() deinit { print("deinitialized!") } } func foo() { let f = Foo()
Ie, f in foo() not de-initialized and, given this strong reference loop, we can conclude that self strongly fixed in the closure instance of the lazy dummy variable.
We can also see that we never create a strong reference loop in case we never create a dummy instance that supports the fact that the simplest lazy instance creation can be considered as a execution area (like if never achieved), which is either a ) has never been achieved (not initialized), or b) achieved, fully executed and “thrown out” (end of area).
class Bar { var foo: Foo? = nil } class Foo { let bar = Bar() lazy var dummy: String = { _ in print("executed") self.bar.foo = self return "dummy" }() deinit { print("deinitialized!") } } func foo() { let p = Foo()
For further reading on strong reference cycles, see for example