【发布时间】:2016-11-03 14:57:08
【问题描述】:
在使用惰性初始化器时,是否有可能出现保留周期?
在blog post 和许多其他地方看到[unowned self]
class Person {
var name: String
lazy var personalizedGreeting: String = {
[unowned self] in
return "Hello, \(self.name)!"
}()
init(name: String) {
self.name = name
}
}
我试过了
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")
}
}
这样用过
//...
let person = Person(name: "name")
print(person.personalizedGreeting)
//..
发现“person deinit”被记录了。
所以似乎没有保留周期。 据我所知,当一个块捕获自我以及当这个块被自我强烈保留时,存在一个保留周期。这种情况看起来类似于保留循环,但实际上并非如此。
【问题讨论】:
-
你试过了吗?添加一个
deinit方法并检查它是否在您期望对象被释放时被调用。或者使用 Xcode/Instruments 中的内存调试工具。 -
当您使用 blocks 或 closures 时,您可能会意外地创建强保留周期——这与
lazy初始化器无关。 -
hello @MartinR deinit 即使没有捕获列表也被调用。
-
@holex 似乎块内存管理在惰性属性方面有所不同。正如答案中所指出的,惰性属性的闭包是隐式的。这改变了此类闭包的内存管理规则。
标签: swift memory-management memory-leaks automatic-ref-counting lazy-initialization