update post
This commit is contained in:
@ -10,11 +10,11 @@ Swift 使用*自动引用计数(ARC)*机制来跟踪和管理你的应用程
|
||||
|
||||
## 自动引用计数的工作机制 {#how-arc-works}
|
||||
|
||||
当你每次创建一个类的新的实例的时候,ARC 会分配一块内存来储存该实例信息。内存中会包含实例的类型信息,以及这个实例所有相关的存储型属性的值。
|
||||
每当你创建一个新的类实例时,ARC 会分配一块内存来储存该实例的信息。内存中会包含实例的类型信息,以及这个实例所关联的任何存储属性的值。
|
||||
|
||||
此外,当实例不再被使用时,ARC 释放实例所占用的内存,并让释放的内存能挪作他用。这确保了不再被使用的实例,不会一直占用内存空间。
|
||||
|
||||
然而,当 ARC 收回和释放了正在被使用中的实例,该实例的属性和方法将不能再被访问和调用。实际上,如果你试图访问这个实例,你的应用程序很可能会崩溃。
|
||||
然而,当 ARC 回收并释放了正在被使用中的实例后,该实例的属性和方法将不能再被访问和调用。实际上,如果你试图访问这个实例,你的应用程序很可能会崩溃。
|
||||
|
||||
为了确保使用中的实例不会被销毁,ARC 会跟踪和计算每一个实例正在被多少属性,常量和变量所引用。哪怕实例的引用数为 1,ARC 都不会销毁这个实例。
|
||||
|
||||
@ -37,9 +37,9 @@ class Person {
|
||||
}
|
||||
```
|
||||
|
||||
`Person` 类有一个构造器,此构造器为实例的 `name` 属性赋值,并打印一条消息以表明初始化过程生效。`Person` 类也拥有一个析构器,这个析构器会在实例被销毁时打印一条消息。
|
||||
`Person` 类有一个构造器,此构造器给实例的 `name` 属性赋值,并打印一条消息以表明初始化过程生效。`Person` 类也拥有一个析构器,这个析构器会在实例被销毁时打印一条消息。
|
||||
|
||||
接下来的代码片段定义了三个类型为 `Person?` 的变量,用来按照代码片段中的顺序,为新的 `Person` 实例建立多个引用。由于这些变量是被定义为可选类型(`Person?`,而不是 `Person`),它们的值会被自动初始化为 `nil`,目前还不会引用到 `Person` 类的实例。
|
||||
接下来的代码片段定义了三个类型为 `Person?` 的变量,按照代码片段中的顺序,为新的 `Person` 实例建立多个引用。由于这些变量是被定义为可选类型(`Person?`,而不是 `Person`),它们的值会被自动初始化为 `nil`,目前还不会引用到 `Person` 类的实例。
|
||||
|
||||
```swift
|
||||
var reference1: Person?
|
||||
@ -87,7 +87,7 @@ reference3 = nil
|
||||
|
||||
然而,我们可能会写出一个类实例的强引用数*永远不能*变成 `0` 的代码。如果两个类实例互相持有对方的强引用,因而每个实例都让对方一直存在,就是这种情况。这就是所谓的*循环强引用*。
|
||||
|
||||
你可以通过定义类之间的关系为弱引用或无主引用,以替代强引用,从而解决循环强引用的问题。具体的过程在 [解决类实例之间的循环强引用](#resolving_strong_reference_cycles_between_class_instances) 中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。
|
||||
你可以通过定义类之间的关系为弱引用或无主引用,来替代强引用,从而解决循环强引用的问题。具体的过程在 [解决类实例之间的循环强引用](#resolving_strong_reference_cycles_between_class_instances) 中有描述。不管怎样,在你学习怎样解决循环强引用之前,很有必要了解一下它是怎样产生的。
|
||||
|
||||
下面展示了一个不经意产生循环强引用的例子。例子定义了两个类:`Person` 和 `Apartment`,用来建模公寓和它其中的居民:
|
||||
|
||||
@ -111,9 +111,9 @@ class Apartment {
|
||||
|
||||
类似的,每个 `Apartment` 实例有一个叫 `unit`,类型为 `String` 的属性,并有一个可选的初始化为 `nil` 的 `tenant` 属性。`tenant` 属性是可选的,因为一栋公寓并不总是有居民。
|
||||
|
||||
这两个类都定义了析构器,用以在类实例被析构的时候输出信息。这让你能够知晓 `Person` 和 `Apartment` 的实例是否像预期的那样被销毁。
|
||||
这两个类都定义了析构器,在类实例被析构的时候输出信息。这让你能够知晓 `Person` 和 `Apartment` 的实例是否像预期的那样被销毁。
|
||||
|
||||
接下来的代码片段定义了两个可选类型的变量 `john` 和 `unit4A`,并分别被设定为下面的 `Apartment` 和 `Person` 的实例。这两个变量都被初始化为 `nil`,这正是可选类型的优点:
|
||||
接下来的代码片段定义了两个可选类型的变量 `john` 和 `unit4A`,并分别被设为下面的 `Apartment` 和 `Person` 的实例。这两个变量都被初始化为 `nil`,这正是可选类型的优点:
|
||||
|
||||
```swift
|
||||
var john: Person?
|
||||
@ -171,7 +171,7 @@ Swift 提供了两种办法用来解决你在使用类的属性时所遇到的
|
||||
|
||||
因为弱引用不会保持所引用的实例,即使引用存在,实例也有可能被销毁。因此,ARC 会在引用的实例被销毁后自动将其弱引用赋值为 `nil`。并且因为弱引用需要在运行时允许被赋值为 `nil`,所以它们会被定义为可选类型变量,而不是常量。
|
||||
|
||||
你可以像其他可选值一样,检查弱引用的值是否存在,你将永远不会访问已销毁的实例的引用。
|
||||
你可以像其他可选值一样,检查弱引用的值是否存在,这样可以避免访问已销毁的实例的引用。
|
||||
|
||||
> 注意
|
||||
>
|
||||
@ -363,7 +363,7 @@ class City {
|
||||
|
||||
由于 `capitalCity` 默认值为 `nil`,一旦 `Country` 的实例在构造器中给 `name` 属性赋值后,整个初始化过程就完成了。这意味着一旦 `name` 属性被赋值后,`Country` 的构造器就能引用并传递隐式的 `self`。`Country` 的构造器在赋值 `capitalCity` 时,就能将 `self` 作为参数传递给 `City` 的构造器。
|
||||
|
||||
以上的意义在于你可以通过一条语句同时创建 `Country` 和 `City` 的实例,而不产生循环强引用,并且 `capitalCity` 的属性能被直接访问,而不需要通过感叹号来展开它的可选值:
|
||||
上述的意义在于你可以通过一条语句同时创建 `Country` 和 `City` 的实例,而不产生循环强引用,并且 `capitalCity` 的属性能被直接访问,而不需要通过感叹号来展开它的可选值:
|
||||
|
||||
```swift
|
||||
var country = Country(name: "Canada", capitalName: "Ottawa")
|
||||
|
||||
Reference in New Issue
Block a user