gpt4 book ai didi

swift - Swift 中的强引用循环

转载 作者:搜寻专家 更新时间:2023-11-01 06:24:49 32 4
gpt4 key购买 nike

我正在查看“The Swift Programming Language”一书的“Unowned References and Implicitly Unwrapped Optional Properties”部分中的示例。

他们的示例代码是

class Country {
let name: String
let capitalCity: City!
init(name: String, capitalName: String) {
self.name = name
self.capitalCity = City(name: capitalName, country: self)
}
}

class City {
let name: String
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
}

如果我想专门处理国家,而 City 类型的唯一目的是成为 Country 的首都,这就可以了。但是如果我想创建一个城市会怎样?

这会产生运行时异常,因为没有保留对 CityCountry 的引用,因为它是一个无主变量:

var chicago = City(name:"Chicago", country: Country(name: "USA", capitalName: "Washington DC"))
chicago.country.name // Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=EXC_I386_GPFLT).

如果不创建强引用循环,我怎么会允许这样的事情发生?

最佳答案

有两种典型的解决方案:

  • 如果您想主要处理城市,请颠倒关系,以便 CityCountryCountry 具有强引用> 指向一个无主实例。

  • 如果您想将城市和国家作为相互交叉引用的主要对象,请将所有城市和国家放入集合(或拥有它们的其他形式的商店)中,并使这两个引用都变弱。这样他们就不会拥有彼此,并且您没有循环。

避免循环保留的最佳方法是考虑谁拥有每个对象。对象可以相互拥有,但这应该是一个清晰的层次结构(即树)。如果您在层次结构中有横向和向上的连接,请将它们设为弱连接或无主连接。

方案一是向上的情况,方案二是横向的情况。

编辑

  • 第三种选择是让 Country 拥有其所有城市的集合。我认为这在这个简单的例子中最有意义,但这意味着 Country 需要在它的初始化中创建所有城市,或者有一个添加城市的方法。

这是第二种情况的示例。它非常复杂,对于这个简单的案例来说可能太复杂了,但它说明了如何提取一个共同的所有者。如果有很多交叉引用,我通常会使用它。 (想想关系数据库。记录不拥有彼此。)

class Country {    let name: String    weak var capitalCity: City?    init(name: String) {        self.name = name    }}class City {    let name: String    unowned let country: Country    init(name: String, country: Country, isCapital: Bool) {        self.name = name        self.country = country        if isCapital {            country.capitalCity = self        }    }}class Planet {    var countries: [Country] = []    var cities: [City] = []}let earth = Planet()earth.countries = [    Country(name: "USA"),    Country(name: "Canada"),]earth.cities = [    City(name: "Washington DC", country: earth.countries[0], isCapital: true),    City(name: "Chicago", country: earth.countries[0], isCapital: false),    City(name: "Ottawa", country: earth.countries[1], isCapital: true),]

关于swift - Swift 中的强引用循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24062824/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com