Strong Reference Cycle
class Person{
init(){
print("Initializing...")
}
deinit{
print("bye")
}
}
let p1 = Person() //This will only print "Initializing..."
var p2 : Person? = Person()
p2 = nil
print("something")
//This time "bye" is also printed
- Reference Counting
- 每一个对象都有一个retain_count (Int),这个count告诉程序,在程序中有几次这个对象被使用到
- 每次reference到这个对象,
retain_count++
,在移除强引用时,retain_count--
- 在retain_count > 0时,这个object被保留在memory中
- 在retain_count == 0时,deinit block被执行
- 没有特殊keyword时,reference默认是strong reference
- Strong Reference Cycle
- 发生在我们assign closure to a property of a class instance
- 这时retain_count永远不会为0,所以永远不会从内存中被移除
- 可以想象,如果程序中有很多这样的strong reference cycle,会占用大量内存
- 解决方法:将一个strong reference变成weak reference(指向object,但不增加retain_count)
这里的closure中self的引用构成了strong reference cycle
- Weak vs Unowned
- 如果指向的object一直存在(在closure存在期间),用
unowned
- 如果object可能为nil,用
weak
- 如果指向的object一直存在(在closure存在期间),用
- Capture List: 将reference定义为
unowned
或weak
的方法
lazy var someClosure: (Int, String) -> String = {
[unowned self, weak delegate] = self.delegate!]
(index: Int, stringToProcess: String) -> String in
// Closure here
}