TL; DR
我有一个结构和一个类。该结构具有对该类实例的引用,而该对象具有捕获该结构的闭包。 如果对该对象的引用是 unowned ,则似乎它们都被取消了初始化。如果对该对象的引用是弱,则它们将彼此保留。 为什么?
我有一个结构和一个类,它们可以相互引用,我试图找出保留周期和打破周期的方法。所以我在操场上玩了一些。
给出以下代码:
struct A {
unowned var b: B
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
do {
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do")
}
如果结构中的var b声明为unowned var b: B
,则释放B对象。如果我将代码修改为weak var b: B?
,然后修改为b?.didSomethingClosure = ...
,则将保留B对象。为什么?
答案 0 :(得分:2)
我想问题是您在Playground
中运行它。尝试在实际应用中运行它,您会发现B
已释放
struct A {
weak var b: B?
init(b: B) {
self.b = b
}
func setup() {
print("A setup")
b?.didSomethingClosure = {
print("A: b did do something")
self.printSomething()
}
}
func printSomething() {
print("A: A did do something")
}
}
class B {
var didSomethingClosure:(() -> Void)?
func doSomething() {
print("B: do something")
didDoSomething()
}
func didDoSomething() {
print("B: did something")
if let closure = didSomethingClosure {
closure()
}
}
deinit {
print("B: deinit")
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let b = B()
let a = A(b: b)
a.setup()
b.doSomething()
print("end do") // B is deallocated here
}
}