正如@ozgur、@jtbandes、@Avi 和@Rob 在评论中解释的那样,没有强引用循环或泄漏。
这是一个基于@Rob 评论的示例,您可以在 Playground 中运行:
class ClassA {
var classB: ClassB?
deinit {
print("ClassA deallocated")
}
}
class ClassB {
deinit {
print("ClassB deallocated")
}
}
class Tester {
func test() {
var myClassA: ClassA! = ClassA()
var myClassB: ClassB! = ClassB() //Reference count 1
myClassA.classB = myClassB //Reference count 2
// Now deallocate
print("setting myClassB to nil")
myClassB = nil //Reference count 1
print("setting myClassA to nil")
myClassA = nil
print("all done")
}
}
// Create `Tester` object and call `test`:
Tester().test()
输出:
setting myClassB to nil
setting myClassA to nil
ClassA deallocated
ClassB deallocated
all done
需要注意的是,即使您设置myClassB
为nil
first,它也会首先myClassA
被释放。当myClassA
被释放时,最终的引用myClassB
被 ARC 释放,然后myClassB
被释放。
为了展示强引用循环,ClassB
请保留对以下内容的强引用ClassA
:
class ClassA {
var classB: ClassB?
deinit {
print("ClassA deallocated")
}
}
class ClassB {
var classA: ClassA?
deinit {
print("ClassB deallocated")
}
}
class Tester {
func test() {
var myClassA:ClassA! = ClassA()
var myClassB:ClassB! = ClassB() //Reference count 1
myClassA.classB = myClassB //Reference count 2
myClassB.classA = myClassA
// Now deallocate
print("setting myClassB to nil")
myClassB = nil //Reference count 1
print("setting myClassA to nil")
myClassA = nil
print("all done")
}
}
Tester().test()
输出:
setting myClassB to nil
setting myClassA to nil
all done
如果它们都包含对另一个的强引用,则两个对象都不会被释放。要打破这个强引用循环,请将classB
或classA
属性之一声明为weak
。您选择哪一个会影响对象被释放的顺序:
如果您weak var classB: ClassB
声明ClassA
:
输出:
setting myClassB to nil
ClassB deallocated
setting myClassA to nil
ClassA deallocated
all done
相反,您声明weak var classA: ClassA in ClassB
:
输出:
setting myClassB to nil
setting myClassA to nil
ClassA deallocated
ClassB deallocated
all done