【问题标题】:Is there no retain cycle in my myClass2?我的 myClass2 中没有保留周期吗?
【发布时间】:2017-10-07 13:48:23
【问题描述】:

有人可以帮助解释为什么 obj2 会得到 deinit 吗? (我认为有一个保留周期)

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

【问题讨论】:

标签: swift retain-cycle


【解决方案1】:

在第二种情况下,最初有一个保留周期,但是当您将变量 obj2 设置为 nil 时,它会中断。

在 Swift 中,闭包通过引用捕获变量(就像在 Objective-C 中当捕获的变量被声明为 __block 时发生的那样),而不是值,因此对闭包外部变量的赋值会反映在闭包中(反之亦然)。闭包只是通过引用捕获的obj2 变量间接引用了myClass2 实例;通过将obj2 设置为nil,你打破了它。

【讨论】:

    猜你喜欢
    • 2014-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    相关资源
    最近更新 更多