电弧弱var Swift(非闭合)

电弧弱var Swift(非闭合),swift,automatic-ref-counting,weak-references,swift-playground,Swift,Automatic Ref Counting,Weak References,Swift Playground,我试图更好地理解ARC,并使用 通过第一个例子,我没有得到苹果所说的预期结果;因为弱引用没有对其引用的实例保持强保留,所以当弱引用仍在引用该实例时,该实例有可能被解除分配。因此,ARC在解除分配其引用的实例时自动将弱引用设置为nil 我在使用XCode 8.3.2中的游乐场 import UIKit class Person { let name: String init(name: String) { self.name = name } var apartment:

我试图更好地理解ARC,并使用

通过第一个例子,我没有得到苹果所说的预期结果;因为弱引用没有对其引用的实例保持强保留,所以当弱引用仍在引用该实例时,该实例有可能被解除分配。因此,ARC在解除分配其引用的实例时自动将弱引用设置为nil

我在使用XCode 8.3.2中的游乐场

import UIKit

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?
    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 //This prints "John Appleseed is being deinitialized" (as expected)
unit4a?.tenant?.name //This shows "John Appleseed" (expected nil)
unit4a = nil //Prints "Unit4a is being deinitialized" (as expected)

我知道这会阻止强引用循环,这样两者都可以被去初始化,但我不明白为什么unit4a会保留对承租人的引用?

你会被右侧游乐场的输出所欺骗,而这些输出与你的印刷品(如去初始化)的时间顺序不同。如果用实际的打印调用替换独立的“回显”,您将在控制台中看到,在打印unit4a?.tenant?.name之后而不是之前,租户将被释放。这是因为弱对象的释放不会立即发生,而是在下一个运行循环中发生。 导入UIKit 导入运动场

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true

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?
    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
print(unit4a?.tenant?.name)
unit4a = nil
输出:

Optional("John Appleseed")
John Appleseed is being deinitialized
Apartment 4A is being deinitialized
但是,如果将最后一位更改为:

john = nil

DispatchQueue.main.asyncAfter(deadline: .now()) {
    print(unit4a?.tenant?.name) //This shows "John Appleseed" (expected nil)
    unit4a = nil //Prints "Unit4a is being deinitialized" (as expected)
}
输出是您所期望的:

John Appleseed is being deinitialized
nil
Apartment 4A is being deinitialized
在大多数情况下,您不会在意对象是否立即被释放,但如果您在意,请查看自动释放池