@ozgur、@jtbandes、@Avi、および @Rob がコメントで説明したように、強い参照サイクルやリークはありません。
Playground で実行できる @Rob のコメントに基づく例を次に示します。
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
しても、それが最初に解放されるということです。が解放されると、 への最終参照がARC によって解放されてから解放されます。nil
myClassA
myClassA
myClassB
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
プロパティの 1 つを に宣言します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