diff --git a/source/chapter2/16_Automatic_Reference_Counting.md b/source/chapter2/16_Automatic_Reference_Counting.md index f4767f16..f9a09b92 100644 --- a/source/chapter2/16_Automatic_Reference_Counting.md +++ b/source/chapter2/16_Automatic_Reference_Counting.md @@ -66,4 +66,44 @@ Person类有一个构造函数,此构造函数为实例的name属性赋值并 现在这个Person类实例已经有三个强引用了。 -(未完待续) +如果你通过给两个变量赋值nil的方式断开两个强引用(包括最先的那个强引用),只留下一个强引用,Person类实例不会被回收: + + reference2 = reference1 + reference3 = reference1 + +ARC会在第三个,也即最后一个强引用被断开的时候,回收Person类实例,这也意味着你不再使用这个Person类实例: + + reference3 = nil + // prints "John Appleseed is being deinitialized" + +## 类实例之间的循环强引用 + +在上面的例子中,ARC会跟踪你所新创建的Person类实例的引用数量,并且会在Person类实例不再被需要时回收它。 + +然而,可能在写的代码中,当类实例的引用数达到零时也不会被回收。这种情况发生在两个类实例互相保持对方的强引用,并让对方不被回收。这就是所谓的循环强引用。 + +你可以通过定义类之间的关系为弱引用或者无主引用,以此替代强引用,从而解决循环强引用的问题。具体的过程在[解决类实例之间的循环强引用](http://numbbbbb.github.io/the-swift-programming-language-in-chinese/chapter2/16_Automatic_Reference_Counting.html#1)中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。 + +这里有一个意外产生循环强引用的例子。例子定义了两个类:Person和Apartment,用来表示一栋公寓和它其中的居民: + + class Person { + let name: String + init(name: String) { self.name = name } + var apartment: Apartment? + deinit { println("\(name) is being deinitialized") } + } + + class Apartment { + let number: Int + init(number: Int) { self.number = number } + var tenant: Person? + deinit { println("Apartment #\(number) is being deinitialized") } + } + +每一个Person类实例有一个类型为String,名字为name的属性并有一个可选的初始化为nil的apartment属性。apartment属性是可选的,因为人并不总是住公寓。 + +类似的,每个Apartment类实例有一个叫number,类型为Int的属性,并有一个可选的初始化为nil的tenant属性。tenant属性是可选的,因为一栋公寓并不总是有租客。 + +这两个类都定义了析构函数,用以在类实例被析构的时候输出信息。这让你能够知晓Person和Apartment的类实例是否按照预想的那样被回收。 + +接下来的代码片段定义了