当前位置:  开发笔记 > 编程语言 > 正文

两个弱变量在Swift中相互引用?

如何解决《两个弱变量在Swift中相互引用?》经验,为你挑选了2个好方法。

我今天再次尝试尝试理解Swift中的保留周期和弱引用.通过阅读文档,我看到了以下代码示例,其中一个引用变量被标记为weak阻止保留周期:

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment? 
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    weak var tenant: Person?             // <---- This var is marked as 'weak'
    deinit { print("Apartment \(unit) is being deinitialized") }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

john = nil // prints "John Appleseed is being deinitialized"
unit4A = nil // prints "Apartment 4A is being deinitialized"

让变量变弱都有问题吗?也就是说,在Person课堂上,我可以将apartment变量变弱,以便我拥有

class Person {
    // ...
    weak var apartment: Apartment?  // added 'weak'
    // ...
}

class Apartment {
    // ...
    weak var tenant: Person?
    // ...
}

其中有两个相互引用的弱变量.

我在游乐场测试了它似乎工作正常,但有没有强烈的理由不这样做?在这种情况下似乎没有自然的亲子关系.



1> Wain..:

你可以做到这一点.唯一的副作用是你需要确保其他东西保留了人和公寓.在原始代码中,您只需要保留人员,公寓(与人相关)将保留给您.

严格来说,当公寓被拆除时人们没有被杀死,当人们死亡时公寓没有被拆除,因此这种情况下的弱参考是有道理的.通常最好考虑您想要的关系和所有权模型,然后决定如何实现这一目标.



2> vacawama..:

为了增加接受的答案,这里是一个演示行为的具体例子.

试试这是一个游乐场:

class Person {
    let name: String
    init(name: String) { self.name = name }
    weak var apartment: Apartment?
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    weak var tenant: Person?             // <---- This var is marked as 'weak'
    deinit { print("Apartment \(unit) is being deinitialized") }
}

class Test {
    var person: Person
    init() {
        person = Person(name: "Fred")
        let unit2B = Apartment(unit: "2B")
        person.apartment = unit2B
        unit2B.tenant = person
        print(person.apartment!.unit)
    }

    func test() {
        print(person.apartment!.unit)
    }
}

func go() {
    let t = Test()
    t.test()  // crashes here!
}

go()

init课堂上Test,已创建的公寓由本地变量保留unit2B.当init完成后,公寓将被释放,因为不再有任何的强引用抱着它,所以当程序崩溃test,是因为所谓的person.apartment现在nil.

如果删除weakfrom weak var apartmentin class Person,则此示例不会崩溃,因为创建的公寓由class属性init保留的personwho保留person.

修复示例的另一种方法是使其unit2B成为属性class Test.然后公寓将有一个强大的参考持有它所以unit2B不会被取消分配后init.

如果weakweak var apartmentin class Person和from weak var tenant中删除class Apartment,那么示例不会崩溃,但是由于两个对象彼此保持强引用而创建的保留周期Person,Apartment因此不会释放也不会释放.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有