diff --git a/source/chapter2/16_Automatic_Reference_Counting.md b/source/chapter2/16_Automatic_Reference_Counting.md index 3fc09d7a..3abb5715 100644 --- a/source/chapter2/16_Automatic_Reference_Counting.md +++ b/source/chapter2/16_Automatic_Reference_Counting.md @@ -9,10 +9,10 @@ - [自动引用计数的工作机制](#how_arc_works) - [自动引用计数实践](#arc_in_action) -- [类实例间的强引用环](#strong_reference_cycles_between_class_instances) -- [类实例间的强引用环分解](#resolving_strong_reference_cycles_between_class_instances) -- [闭包的强引用环](#strong_reference_cycles_for_closures) -- [闭包的强引用环分解](#resolving_strong_reference_cycles_for_closures) +- [类实例之间的循环强引用](#strong_reference_cycles_between_class_instances) +- [解决实例之间的循环强引用](#resolving_strong_reference_cycles_between_class_instances) +- [闭包引起的循环强引用](#strong_reference_cycles_for_closures) +- [解决闭包引起的循环强引用](#resolving_strong_reference_cycles_for_closures) Swift 使用自动引用计数(ARC)这一机制来跟踪和管理你的应用程序的内存。通常情况下,Swift 的内存管理机制会一直起着作用,你无须自己来考虑内存的管理。ARC 会在类的实例不再被使用时,自动释放其占用的内存。 @@ -34,7 +34,7 @@ Swift 使用自动引用计数(ARC)这一机制来跟踪和管理你的应 为了使之成为可能,无论你将实例赋值给属性,常量或者是变量,属性,常量或者变量,都会对此实例创建强引用。之所以称之为强引用,是因为它会将实例牢牢的保持住,只要强引用还在,实例是不允许被销毁的。 -## 自动引用计数实战 +## 自动引用计数实践 下面的例子展示了自动引用计数的工作机制。例子以一个简单的`Person`类开始,并定义了一个叫`name`的常量属性: @@ -92,7 +92,7 @@ ARC 会在第三个,也即最后一个强引用被断开的时候,销毁`Per 然而,我们可能会写出这样的代码,一个类永远不会有0个强引用。这种情况发生在两个类实例互相保持对方的强引用,并让对方不被销毁。这就是所谓的循环强引用。 -你可以通过定义类之间的关系为弱引用或者无主引用,以此替代强引用,从而解决循环强引用的问题。具体的过程在[解决类实例之间的循环强引用](#1)中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。 +你可以通过定义类之间的关系为弱引用或者无主引用,以此替代强引用,从而解决循环强引用的问题。具体的过程在[解决类实例之间的循环强引用](#resolving_strong_reference_cycles_between_class_instances)中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。 下面展示了一个不经意产生循环强引用的例子。例子定义了两个类:`Person`和`Apartment`,用来建模公寓和它其中的居民: @@ -153,7 +153,7 @@ ARC 会在第三个,也即最后一个强引用被断开的时候,销毁`Per `Person`和`Apartment`实例之间的强引用关系保留了下来并且不会被断开。 -##解决实例之间的循环强引用 +## 解决实例之间的循环强引用 Swift 提供了两种办法用来解决你在使用类的属性时所遇到的循环强引用问题:弱引用(weak reference)和无主引用(unowned reference)。 @@ -169,8 +169,7 @@ Swift 提供了两种办法用来解决你在使用类的属性时所遇到的 在实例的生命周期中,如果某些时候引用没有值,那么弱引用可以阻止循环强引用。如果引用总是有值,则可以使用无主引用,在[无主引用](#2)中有描述。在上面`Apartment`的例子中,一个公寓的生命周期中,有时是没有“居民”的,因此适合使用弱引用来解决循环强引用。 > 注意: -> -弱引用必须被声明为变量,表明其值能在运行时被修改。弱引用不能被声明为常量。 +> 弱引用必须被声明为变量,表明其值能在运行时被修改。弱引用不能被声明为常量。 因为弱引用可以没有值,你必须将每一个弱引用声明为可选类型。可选类型是在 Swift 语言中推荐的用来表示可能没有值的类型。 @@ -227,7 +226,8 @@ Swift 提供了两种办法用来解决你在使用类的属性时所遇到的 上面的两段代码展示了变量`john`和`number73`在被赋值为`nil`后,`Person`实例和`Apartment`实例的析构函数都打印出“销毁”的信息。这证明了引用循环被打破了。 -###无主引用 + +### 无主引用 和弱引用类似,无主引用不会牢牢保持住引用的实例。和弱引用不同的是,无主引用是永远有值的。因此,无主引用总是被定义为非可选类型(non-optional type)。你可以在声明属性或者变量时,在前面加上关键字`unowned`表示这是一个无主引用。 @@ -418,6 +418,7 @@ Swift 提供了一种优雅的方法来解决这个问题,称之为闭包占 注意`HTMLElementdeinitializer`中的消息并没有别打印,证明了`HTMLElement`实例并没有被销毁。 + ##解决闭包引起的循环强引用 在定义闭包时同时定义占有列表作为闭包的一部分,通过这种方式可以解决闭包和类实例之间的循环强引用。占有列表定义了闭包体内占有一个或者多个引用类型的规则。跟解决两个类实例间的循环强引用一样,声明每个占有的引用为弱引用或无主引用,而不是强引用。应当根据代码关系来决定使用弱引用还是无主引用。 @@ -454,7 +455,7 @@ Swift 有如下要求:只要在闭包内使用`self`的成员,就要用`self > 如果占有的引用绝对不会置为`nil`,应该用无主引用,而不是弱引用。 -前面的`HTMLElement`例子中,无主引用是正确的解决循环强引用的方法。这样这样编写`HTMLElement`类来避免循环强引用: +前面的`HTMLElement`例子中,无主引用是正确的解决循环强引用的方法。这样编写`HTMLElement`类来避免循环强引用: class HTMLElement {