ARC weak var Swift(不是闭包)
ARC weak var Swift (not closures)
我正在努力更好地理解 ARC 并正在使用 Apples Documentation
通过第一个示例,我没有得到 Apple 声明的预期结果; "Because a weak reference does not keep a strong hold on the instance it refers to, it’s possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated."
我在 XCode 8.3.2
中使用 playground
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 保留对租户的引用?
您被右侧 playgrounds 的输出所欺骗,它与您的印刷品(如 deinits 中)的时间顺序不同。如果将独立 "echoes" 替换为实际的打印调用,您将在控制台中看到租户在您打印 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
在大多数情况下,您不会在意对象是否会立即释放,但如果您在意,请查看自动释放池
我正在努力更好地理解 ARC 并正在使用 Apples Documentation
通过第一个示例,我没有得到 Apple 声明的预期结果; "Because a weak reference does not keep a strong hold on the instance it refers to, it’s possible for that instance to be deallocated while the weak reference is still referring to it. Therefore, ARC automatically sets a weak reference to nil when the instance that it refers to is deallocated."
我在 XCode 8.3.2
中使用 playgroundimport 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 保留对租户的引用?
您被右侧 playgrounds 的输出所欺骗,它与您的印刷品(如 deinits 中)的时间顺序不同。如果将独立 "echoes" 替换为实际的打印调用,您将在控制台中看到租户在您打印 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
在大多数情况下,您不会在意对象是否会立即释放,但如果您在意,请查看自动释放池