From 4b423c1cabc7addba31d8d48ffa7150a14e03b3b Mon Sep 17 00:00:00 2001 From: Timothy Date: Wed, 11 Jun 2014 23:07:54 +0800 Subject: [PATCH 1/3] update reference pages --- source/chapter2/16_Automatic_Reference_Counting.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/source/chapter2/16_Automatic_Reference_Counting.md b/source/chapter2/16_Automatic_Reference_Counting.md index 603fc1f7..a5fada1a 100644 --- a/source/chapter2/16_Automatic_Reference_Counting.md +++ b/source/chapter2/16_Automatic_Reference_Counting.md @@ -83,7 +83,7 @@ ARC会在第三个,也即最后一个强引用被断开的时候,销毁Perso 然而,我们可能会写出这样的代码,一个类永远不会有0个强引用。这种情况发生在两个类实例互相保持对方的强引用,并让对方不被销毁。这就是所谓的循环强引用。 -你可以通过定义类之间的关系为弱引用或者无主引用,以此替代强引用,从而解决循环强引用的问题。具体的过程在[解决类实例之间的循环强引用](http://numbbbbb.github.io/the-swift-programming-language-in-chinese/chapter2/16_Automatic_Reference_Counting.html#1)中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。 +你可以通过定义类之间的关系为弱引用或者无主引用,以此替代强引用,从而解决循环强引用的问题。具体的过程在[解决类实例之间的循环强引用](#1)中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。 下面展示了一个不经意产生循环强引用的例子。例子定义了两个类:Person和Apartment,用来建模公寓和它其中的居民: @@ -143,7 +143,7 @@ ARC会在第三个,也即最后一个强引用被断开的时候,销毁Perso Person和Apartment实例之间的强引用关系保留了下来并且不会被断开。 -##解决实例之间的循环强引用 +##解决实例之间的循环强引用 Swift提供了两种办法用来解决你在使用类的属性时所遇到的循环强引用问题:弱引用(weak reference)和无主引用(unowned reference)。 @@ -155,7 +155,7 @@ Swift提供了两种办法用来解决你在使用类的属性时所遇到的循 弱引用不会牢牢保持住引用的实例,并且不会阻止ARC销毁被引用的实例。这种行为阻止了引用变为循环强引用。声明属性或者变量时,在前面加上weak关键字表明这是一个弱引用。 -在实例的生命周期中,如果某些时候引用没有值,那么弱引用可以阻止循环强引用。如果引用总是有值,则可以使用无主引用,在[无主引用](http://numbbbbb.github.io/the-swift-programming-language-in-chinese/chapter2/16_Automatic_Reference_Counting.html#2)中有描述。在上面Apartment的例子中,一个公寓的生命周期中,有时是没有“居民”的,因此适合使用弱引用来解决循环强引用。 +在实例的生命周期中,如果某些时候引用没有值,那么弱引用可以阻止循环强引用。如果引用总是有值,则可以使用无主引用,在[无主引用](#2)中有描述。在上面Apartment的例子中,一个公寓的生命周期中,有时是没有“居民”的,因此适合使用弱引用来解决循环强引用。 > 注意: 弱引用必须被声明为变量,表明其值能在运行时被修改。弱引用不能被声明为常量。 @@ -214,7 +214,7 @@ Person实例依然保持对Apartment实例的强引用,但是Apartment实例 上面的两段代码展示了变量john和number73在被赋值为nil后,Person实例和Apartment实例的析构函数都打印出“销毁”的信息。这证明了引用循环被打破了。 -##无主引用 +##无主引用 和弱引用类似,无主引用不会牢牢保持住引用的实例。和弱引用不同的是,无主引用是永远有值的。因此,无主引用总是被定义为非可选类型(non-optional type)。你可以在声明属性或者变量时,在前面加上关键字unowned表示这是一个无主引用。 @@ -312,9 +312,9 @@ Customer和CreditCard的例子展示了一个属性的值允许为nil,而另 为了建立两个类的依赖关系,City的构造函数有一个Country实例的参数,并且将实例保存为country属性。 -Country的构造函数调用了City的构造函数。然而,只有Country的实例完全初始化完后,Country的构造函数才能把self传给City的构造函数。([在两阶段构造函数中有具体描述](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_288)) +Country的构造函数调用了City的构造函数。然而,只有Country的实例完全初始化完后,Country的构造函数才能把self传给City的构造函数。([在两步构造函数中有具体描述](./14_Initialization.html) -为了满足这种需求,通过在类型结尾处加上感叹号(City!)的方式,将Country的capitalCity属性声明为显示展开的可选类型属性。这表示像其他可选类型一样,capitalCity属性的默认值为nil,但是不需要展开他的值就能访问它。([在显示展开的可选类型中有描述](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_436)) +为了满足这种需求,通过在类型结尾处加上感叹号(City!)的方式,将Country的capitalCity属性声明为显示展开的可选类型属性。这表示像其他可选类型一样,capitalCity属性的默认值为nil,但是不需要展开他的值就能访问它。([在显示展开的可选类型中有描述](./01_The_Basics.html)) 由于capitalCity默认值为nil,一旦Country的实例在构造函数中给name属性赋值后,整个初始化过程就完成了。这代表一旦name属性被后,Country的构造函数就能引用并传递显式的self。Country的构造函数在赋值capitalCity时,就能将self作为参数传递给City的构造函数。 @@ -386,7 +386,7 @@ HTMLElement类只提供一个构造函数,通过name和text(如果有的话) ![](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Art/closureReferenceCycle01_2x.png) -实例的asHTML属性持有闭包的强引用。但是,闭包在其闭包体内使用了self(引用了self.name和self.text),因此闭包占有了self,这意味着闭包又反过来持有了HTMLElement实例的强引用。这样两个对象就产生了循环强引用。(更多关于闭包占有值的信息,请参考[Capturing Values](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-XID_129))。 +实例的asHTML属性持有闭包的强引用。但是,闭包在其闭包体内使用了self(引用了self.name和self.text),因此闭包占有了self,这意味着闭包又反过来持有了HTMLElement实例的强引用。这样两个对象就产生了循环强引用。(更多关于闭包占有值的信息,请参考[值捕获](./07_Closures.html))。 >注意: 虽然闭包多次使用了self,它只占有HTMLElement实例的一个强引用。 From 76789e432185fd3fd3d59ebac82ecbd6fec5a181 Mon Sep 17 00:00:00 2001 From: Timothy Date: Wed, 11 Jun 2014 23:07:54 +0800 Subject: [PATCH 2/3] update reference pages --- source/chapter2/16_Automatic_Reference_Counting.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/chapter2/16_Automatic_Reference_Counting.md b/source/chapter2/16_Automatic_Reference_Counting.md index 3fc09d7a..c8d8147b 100644 --- a/source/chapter2/16_Automatic_Reference_Counting.md +++ b/source/chapter2/16_Automatic_Reference_Counting.md @@ -166,6 +166,8 @@ Swift 提供了两种办法用来解决你在使用类的属性时所遇到的 弱引用不会牢牢保持住引用的实例,并且不会阻止 ARC 销毁被引用的实例。这种行为阻止了引用变为循环强引用。声明属性或者变量时,在前面加上`weak`关键字表明这是一个弱引用。 +在实例的生命周期中,如果某些时候引用没有值,那么弱引用可以阻止循环强引用。如果引用总是有值,则可以使用无主引用,在[无主引用](#2)中有描述。在上面Apartment的例子中,一个公寓的生命周期中,有时是没有“居民”的,因此适合使用弱引用来解决循环强引用。 + 在实例的生命周期中,如果某些时候引用没有值,那么弱引用可以阻止循环强引用。如果引用总是有值,则可以使用无主引用,在[无主引用](#2)中有描述。在上面`Apartment`的例子中,一个公寓的生命周期中,有时是没有“居民”的,因此适合使用弱引用来解决循环强引用。 > 注意: @@ -406,7 +408,11 @@ Swift 提供了一种优雅的方法来解决这个问题,称之为闭包占 ![](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Art/closureReferenceCycle01_2x.png) +<<<<<<< HEAD 实例的`asHTML`属性持有闭包的强引用。但是,闭包在其闭包体内使用了`self`(引用了`self.name`和`self.text`),因此闭包占有了`self`,这意味着闭包又反过来持有了`HTMLElement`实例的强引用。这样两个对象就产生了循环强引用。(更多关于闭包占有值的信息,请参考[值捕获](07_Closures.html))。 +======= +实例的asHTML属性持有闭包的强引用。但是,闭包在其闭包体内使用了self(引用了self.name和self.text),因此闭包占有了self,这意味着闭包又反过来持有了HTMLElement实例的强引用。这样两个对象就产生了循环强引用。(更多关于闭包占有值的信息,请参考[值捕获](./07_Closures.html))。 +>>>>>>> update reference pages >注意: > From 8d422ffb14cd4a84f3a937abeac66aa86c768589 Mon Sep 17 00:00:00 2001 From: Timothy Date: Thu, 12 Jun 2014 22:25:49 +0800 Subject: [PATCH 3/3] update ARC, fix some bugs & typing errors --- .../16_Automatic_Reference_Counting.md | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) 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 {