@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
> 2.1
|
> 2.1
|
||||||
> 翻译:[Channe](https://github.com/Channe)
|
> 翻译:[Channe](https://github.com/Channe)
|
||||||
> 校对:[shanks](http://codebuild.me),2015-10-31
|
> 校对:[shanks](http://codebuild.me),[Realank](https://github.com/Realank) ,2016-01-23
|
||||||
|
|
||||||
本页包含内容:
|
本页包含内容:
|
||||||
|
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用程序的内存。通常情况下,Swift 内存管理机制会一直起作用,你无须自己来考虑内存的管理。ARC 会在类的实例不再被使用时,自动释放其占用的内存。
|
Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用程序的内存。通常情况下,Swift 内存管理机制会一直起作用,你无须自己来考虑内存的管理。ARC 会在类的实例不再被使用时,自动释放其占用的内存。
|
||||||
|
|
||||||
然而,在少数情况下,ARC 为了能帮助你管理内存,需要更多的关于你的代码之间关系的信息。本章描述了这些情况,并且为你示范怎样启用 ARC 来管理你的应用程序的内存。
|
然而在少数情况下,为了能帮助你管理内存,ARC 需要更多的,代码之间关系的信息。本章描述了这些情况,并且为你示范怎样才能使 ARC 来管理你的应用程序的所有内存。
|
||||||
|
|
||||||
> 注意
|
> 注意
|
||||||
引用计数仅仅应用于类的实例。结构体和枚举类型是值类型,不是引用类型,也不是通过引用的方式存储和传递。
|
引用计数仅仅应用于类的实例。结构体和枚举类型是值类型,不是引用类型,也不是通过引用的方式存储和传递。
|
||||||
@ -31,7 +31,7 @@ Swift 使用自动引用计数(ARC)机制来跟踪和管理你的应用程
|
|||||||
<a name="how_arc_works"></a>
|
<a name="how_arc_works"></a>
|
||||||
## 自动引用计数的工作机制
|
## 自动引用计数的工作机制
|
||||||
|
|
||||||
当你每次创建一个类的新的实例的时候,ARC 会分配一大块内存用来储存实例的信息。内存中会包含实例的类型信息,以及这个实例所有相关属性的值。
|
当你每次创建一个类的新的实例的时候,ARC 会分配一块内存来储存该实例信息。内存中会包含实例的类型信息,以及这个实例所有相关的存储型属性的值。
|
||||||
|
|
||||||
此外,当实例不再被使用时,ARC 释放实例所占用的内存,并让释放的内存能挪作他用。这确保了不再被使用的实例,不会一直占用内存空间。
|
此外,当实例不再被使用时,ARC 释放实例所占用的内存,并让释放的内存能挪作他用。这确保了不再被使用的实例,不会一直占用内存空间。
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ class Apartment {
|
|||||||
|
|
||||||
每一个`Person`实例有一个类型为`String`,名字为`name`的属性,并有一个可选的初始化为`nil`的`apartment`属性。`apartment`属性是可选的,因为一个人并不总是拥有公寓。
|
每一个`Person`实例有一个类型为`String`,名字为`name`的属性,并有一个可选的初始化为`nil`的`apartment`属性。`apartment`属性是可选的,因为一个人并不总是拥有公寓。
|
||||||
|
|
||||||
类似的,每个`Apartment`实例有一个叫`number`,类型为`Int`的属性,并有一个可选的初始化为`nil`的`tenant`属性。`tenant`属性是可选的,因为一栋公寓并不总是有居民。
|
类似的,每个`Apartment`实例有一个叫`unit`,类型为`String`的属性,并有一个可选的初始化为`nil`的`tenant`属性。`tenant`属性是可选的,因为一栋公寓并不总是有居民。
|
||||||
|
|
||||||
这两个类都定义了析构函数,用以在类实例被析构的时候输出信息。这让你能够知晓`Person`和`Apartment`的实例是否像预期的那样被销毁。
|
这两个类都定义了析构函数,用以在类实例被析构的时候输出信息。这让你能够知晓`Person`和`Apartment`的实例是否像预期的那样被销毁。
|
||||||
|
|
||||||
@ -411,7 +411,7 @@ print("\(country.name)'s capital city is called \(country.capitalCity.name)")
|
|||||||
|
|
||||||
循环强引用的产生,是因为闭包和类相似,都是引用类型。当你把一个闭包赋值给某个属性时,你是将这个闭包的引用赋值给了属性。实质上,这跟之前的问题是一样的——两个强引用让彼此一直有效。但是,和两个类实例不同,这次一个是类实例,另一个是闭包。
|
循环强引用的产生,是因为闭包和类相似,都是引用类型。当你把一个闭包赋值给某个属性时,你是将这个闭包的引用赋值给了属性。实质上,这跟之前的问题是一样的——两个强引用让彼此一直有效。但是,和两个类实例不同,这次一个是类实例,另一个是闭包。
|
||||||
|
|
||||||
Swift 提供了一种优雅的方法来解决这个问题,称之为闭包捕获列表(closuer capture list)。同样的,在学习如何用闭包捕获列表破坏循环强引用之前,先来了解一下这里的循环强引用是如何产生的,这对我们很有帮助。
|
Swift 提供了一种优雅的方法来解决这个问题,称之为`闭包捕获列表`(closure capture list)。同样的,在学习如何用闭包捕获列表打破循环强引用之前,先来了解一下这里的循环强引用是如何产生的,这对我们很有帮助。
|
||||||
|
|
||||||
下面的例子为你展示了当一个闭包引用了`self`后是如何产生一个循环强引用的。例子中定义了一个叫`HTMLElement`的类,用一种简单的模型表示 HTML 文档中的一个单独的元素:
|
下面的例子为你展示了当一个闭包引用了`self`后是如何产生一个循环强引用的。例子中定义了一个叫`HTMLElement`的类,用一种简单的模型表示 HTML 文档中的一个单独的元素:
|
||||||
|
|
||||||
@ -471,7 +471,7 @@ print(heading.asHTML())
|
|||||||
```swift
|
```swift
|
||||||
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
|
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
|
||||||
print(paragraph!.asHTML())
|
print(paragraph!.asHTML())
|
||||||
// 打印 “hello, world”
|
// 打印 “<p>hello, world</p>”
|
||||||
```
|
```
|
||||||
|
|
||||||
> 注意
|
> 注意
|
||||||
@ -528,9 +528,9 @@ lazy var someClosure: Void -> String = {
|
|||||||
<a name="weak_and_unowned_references"></a>
|
<a name="weak_and_unowned_references"></a>
|
||||||
###弱引用和无主引用
|
###弱引用和无主引用
|
||||||
|
|
||||||
在闭包和捕获的实例总是互相引用并且总是同时销毁时,将闭包内的捕获定义为无主引用。
|
在闭包和捕获的实例总是互相引用并且总是同时销毁时,将闭包内的捕获定义为`无主引用`。
|
||||||
|
|
||||||
相反的,在被捕获的引用可能会变为`nil`时,将闭包内的捕获定义为弱引用。弱引用总是可选类型,并且当引用的实例被销毁后,弱引用的值会自动置为`nil`。这使我们可以在闭包体内检查它们是否存在。
|
相反的,在被捕获的引用可能会变为`nil`时,将闭包内的捕获定义为`弱引用`。弱引用总是可选类型,并且当引用的实例被销毁后,弱引用的值会自动置为`nil`。这使我们可以在闭包体内检查它们是否存在。
|
||||||
|
|
||||||
> 注意
|
> 注意
|
||||||
如果被捕获的引用绝对不会变为`nil`,应该用无主引用,而不是弱引用。
|
如果被捕获的引用绝对不会变为`nil`,应该用无主引用,而不是弱引用。
|
||||||
|
|||||||
Reference in New Issue
Block a user