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
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
}