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池