finally adjust

This commit is contained in:
梁杰
2015-08-02 22:12:05 +08:00
parent 15321c7a74
commit 2044f4667f
37 changed files with 1923 additions and 1668 deletions

View File

@ -1,6 +1,10 @@
> 1.0
> 翻译:[TimothyYe](https://github.com/TimothyYe)
> 校对:[Hawstein](https://github.com/Hawstein)
> 2.0
> 翻译+校对:[Channe](https://github.com/Channe)
# 自动引用计数
-----------------
@ -23,8 +27,8 @@ Swift 使用自动引用计数ARC机制来跟踪和管理你的应用程
<a name="how_arc_works"></a>
## 自动引用计数的工作机制
当你每次创建一个类的新的实例的时候ARC 会分配一大块内存用来储存实例的信息。内存中会包含实例的类型信息,以及这个实例所有相关属性的值。
当你每次创建一个类的新的实例的时候ARC 会分配一大块内存用来储存实例的信息。内存中会包含实例的类型信息,以及这个实例所有相关属性的值。
此外当实例不再被使用时ARC 释放实例所占用的内存,并让释放的内存能挪作他用。这确保了不再被使用的实例,不会一直占用内存空间。
然而,当 ARC 收回和释放了正在被使用中的实例,该实例的属性和方法将不能再被访问和调用。实际上,如果你试图访问这个实例,你的应用程序很可能会崩溃。
@ -86,8 +90,8 @@ reference3 = reference1
```swift
reference1 = nil
reference2 = nil
```
```
在你清楚地表明不再使用这个`Person`实例时即第三个也就是最后一个强引用被断开时ARC 会销毁它。
```swift
@ -158,7 +162,7 @@ number73!.tenant = john
在将两个实例联系在一起之后,强引用的关系如图所示:
![](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Art/referenceCycle02_2x.png)
不幸的是,这两个实例关联后会产生一个循环强引用。`Person`实例现在有了一个指向`Apartment`实例的强引用,而`Apartment`实例也有了一个指向`Person`实例的强引用。因此,当你断开`john``number73`变量所持有的强引用时,引用计数并不会降为 0实例也不会被 ARC 销毁:
```swift
@ -184,7 +188,7 @@ Swift 提供了两种办法用来解决你在使用类的属性时所遇到的
对于生命周期中会变为`nil`的实例使用弱引用。相反地,对于初始化赋值后再也不会被赋值为`nil`的实例,使用无主引用。
### 弱引用
弱引用不会对其引用的实例保持强引用,因而不会阻止 ARC 销毁被引用的实例。这个特性阻止了引用变为循环强引用。声明属性或者变量时,在前面加上`weak`关键字表明这是一个弱引用。
在实例的生命周期中,如果某些时候引用没有值,那么弱引用可以避免循环强引用。如果引用总是有值,则可以使用无主引用,在[无主引用](#2)中有描述。在上面`Apartment`的例子中,一个公寓的生命周期中,有时是没有“居民”的,因此适合使用弱引用来解决循环强引用。
@ -297,9 +301,9 @@ class CreditCard {
}
deinit { print("Card #\(number) is being deinitialized") }
}
```
> 注意:
```
> 注意:
> `CreditCard`类的`number`属性被定义为`UInt64`类型而不是`Int`类型,以确保`number`属性的存储量在32位和64位系统上都能足够容纳16位的卡号。
下面的代码片段定义了一个叫`john`的可选类型`Customer`变量,用来保存某个特定客户的引用。由于是可选类型,所以变量被初始化为`nil`
@ -335,6 +339,8 @@ john = nil
最后的代码展示了在`john`变量被设为`nil``Customer`实例和`CreditCard`实例的构造函数都打印出了“销毁”的信息。
<a name="unowned_references_and_implicitly_unwrapped_optional_properties"></a>
###无主引用以及隐式解析可选属性
上面弱引用和无主引用的例子涵盖了两种常用的需要打破循环强引用的场景。
@ -373,9 +379,9 @@ class City {
为了建立两个类的依赖关系,`City`的构造函数有一个`Country`实例的参数,并且将实例保存为`country`属性。
`Country`的构造函数调用了`City`的构造函数。然而,只有`Country`的实例完全初始化完后,`Country`的构造函数才能把`self`传给`City`的构造函数。([两段式构造过程中有具体描述](14_Initialization.html)
`Country`的构造函数调用了`City`的构造函数。然而,只有`Country`的实例完全初始化完后,`Country`的构造函数才能把`self`传给`City`的构造函数。([两段式构造过程](./14_Initialization.html#two_phase_initialization)中有具体描述
为了满足这种需求,通过在类型结尾处加上感叹号(`City!`)的方式,将`Country``capitalCity`属性声明为隐式解析可选类型的属性。这表示像其他可选类型一样,`capitalCity`属性的默认值为`nil`,但是不需要展开它的值就能访问它。([隐式解析可选类型中有描述](01_The_Basics.html)
为了满足这种需求,通过在类型结尾处加上感叹号(`City!`)的方式,将`Country``capitalCity`属性声明为隐式解析可选类型的属性。这表示像其他可选类型一样,`capitalCity`属性的默认值为`nil`,但是不需要展开它的值就能访问它。([隐式解析可选类型](./01_The_Basics.html#implicityly_unwrapped_optionals)中有描述
由于`capitalCity`默认值为`nil`,一旦`Country`的实例在构造函数中给`name`属性赋值后,整个初始化过程就完成了。这代表一旦`name`属性被赋值后,`Country`的构造函数就能引用并传递隐式的`self``Country`的构造函数在赋值`capitalCity`时,就能将`self`作为参数传递给`City`的构造函数。
@ -456,7 +462,7 @@ print(paragraph!.asHTML())
![](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`实例的强引用。这样两个对象就产生了循环强引用。(更多关于闭包捕获值的信息,请参考[值捕获](07_Closures.html))。
实例的`asHTML`属性持有闭包的强引用。但是,闭包在其闭包体内使用了`self`(引用了`self.name``self.text`),因此闭包捕获了`self`,这意味着闭包又反过来持有了`HTMLElement`实例的强引用。这样两个对象就产生了循环强引用。(更多关于闭包捕获值的信息,请参考[值捕获](./07_Closures.html#capturing_values))。
>注意:
虽然闭包多次使用了`self`,它只捕获`HTMLElement`实例的一个强引用。
@ -477,9 +483,9 @@ paragraph = nil
>注意:
Swift 有如下要求:只要在闭包内使用`self`的成员,就要用`self.someProperty`或者`self.someMethod`(而不只是`someProperty``someMethod`)。这提醒你可能会一不小心就捕获了`self`
###定义捕获列表
###定义捕获列表
捕获列表中的每一项都由一对元素组成,一个元素是`weak``unowned`关键字,另一个元素是类实例的引用(如`self`)或初始化过的变量(如`delegate = self.delegate!`)。这些项在方括号中用逗号分开。
捕获列表中的每一项都由一对元素组成,一个元素是`weak``unowned`关键字,另一个元素是类实例的引用(如`self`)或初始化过的变量(如`delegate = self.delegate!`)。这些项在方括号中用逗号分开。
如果闭包有参数列表和返回类型,把捕获列表放在它们前面: