2017-10-07 15 views
4

有人可以帮助解释为什么obj2会被取消吗? (我认为有一个保留周期)我的myClass2中没有保留循环吗?

OBJ2和OBJ1是如此相似: 他们都有一个名为printNameLength属性,这两者是一个封闭,这既捕获自(是吗?)。

但obj2得到deinit(而obj1不是因为有一个保留周期),它让我感到惊讶,我不知道为什么。

非常感谢。

class myClass1 { 

    var name: String 

    lazy var printNameLength: (() -> Int) = { // [unowned self] 
     return self.name.characters.count // retain cycle here 
    } 

    init(name: String){ 
     self.name = name 
    } 

    deinit { 
     print("deinit myClass1: \(name)") 
    } 

} 

var obj1: myClass1? = myClass1.init(name: "obj1") 
print(obj1!.printNameLength()) 
obj1 = nil // never get deinit 



class myClass2{ 
    var name: String 

    init(name: String){ 
     self.name = name 
    } 

    var printNameLength: (() -> Int)? 

    deinit { 
     print("deinit myClass2: \(name)") 
    } 
} 

var obj2: myClass2? = myClass2.init(name: "obj2") 
obj2!.printNameLength = { 
    return obj2!.name.characters.count // no retain cycle here? 
} 
print(obj2!.printNameLength!()) 
obj2 = nil // get deinit 
+2

比较https://stackoverflow.com/q/40978533/2976878 – Hamish

回答

0

在第二种情况下,有一个保留周期开始,但是当你设置变量obj2nil它被打破。

在Swift中,闭包通过引用捕获变量(比如在声明__block时捕获到的变量在Objective-C中发生的变化),因此闭包之外的变量的赋值会反映在闭包中(反之亦然) 。关闭只间接地参照myClass2实例,通过引用捕获的obj2变量;通过将obj2设置为nil,您打破了这一点。