1

我想更好地了解ARC和正在使用Apples DocumentationARC弱VAR斯威夫特(未封闭)

通过的第一个例子去我没有得到期望的结果,苹果的状态; “因为弱引用并没有对它所指的实例持有强大的保留,所以可能会将该实例解除分配,而弱引用仍然指向该实例。因此,ARC会自动将弱引用设置为零,它指的是被释放。“

林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) 

我明白,这阻止了有力的参考周期,这样既可以deinitialized但我不理解为什么unit4a保持对租户参考使用操场?

回答

-1

你被右边的游乐场的输出所欺骗,它与你的印刷品没有相同的时间顺序(如在诽谤中)。如果用实际的打印呼叫替换独立的“回声”,您会看到在控制台中,在打印unit4a?.tenant?.name而不是之前,租户被释放。这是因为弱对象的释放不会立即发生,而是在下一次运行循环中。 进口的UIKit 进口XCPlayground

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 

在大多数情况下,您并不在意该对象是否立即释放,但如果您这样做,请查看autorelease池