自动引用计数(Automatic Reference Counting)简称ARC
ARC机制最主要的功能是自动回收系统分配给类实例的空间。
什么是强引用环:在两个类实例彼此保持对方的强引用,使得每个实例都使对方保持有效时会发生这种情况。我们称之为强引用环。
Swift提供了三种方法来解决强引用:
三种方法对应的场景:
关键字weak表明引用为弱引用。
注意:弱引用只能声明为变量类型,因为运行时它的值可能改变。弱引用绝对不能声明为常量。
因为弱引用可以没有值,所以声明弱引用的时候必须是可选类型的。在Swift语言中,推荐用可选类型来作为可能没有值的引用的类型。
class Person { let name: String init(name: String) { self.name = name } var apartment: Apartment? deinit { println("\(name) is being deinitialized") } } class Apartment { let number: Int init(number: Int) { self.number = number } weak var tenant: Person? // 弱引用 deinit { println("Apartment #\(number) is being deinitialized") } }
在属性、变量前添加unowned关键字,可以声明一个无主引用。
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { println("\(name) is being deinitialized") } class CreditCard { let number: Int unowned let customer: Customer // 无主引用 init(number: Int, customer: Customer) { self.number = number self.customer = customer }
// 析构器 deinit { println("Card #\(number) is being deinitialized") }
在类型结尾处加感叹号(City!),表示为隐式展开的可选类型属性。就是说,capitalCity属性的默认值是nil,不需要展开它的值就可以直接访问。
class Country { let name: String let capitalCity: City! // 隐式展开的可选属性,默认值是nil init(name: String, capitalName: String) { self.name = name // capitalCity 在此处默认值nil self.capitalCity = City(name: capitalName, country: self) } } class City { let name: String unowned let country: Country // 无主引用 init(name: String, country: Country) { self.name = name self.country = country } }
因为capitalCity默认值是nil,一旦Country的实例在初始化时给name属性赋值后,整个初始化过程就完成了。这代表只要赋值name属性后,Country的初始化函数就能引用并传递隐式的self。所以,当Country的初始化函数在赋值capitalCity时,它也可以将self作为参数传递给City的初始化函数。
综上所述,你可以在一条语句中同时创建Country和City的实例,却不会产生强引用环,并且不需要使用感叹号来展开它的可选值就可以直接访问capitalCity:
var country = Country(name: "Canada", capitalName: "Ottawa") println("\(country.name)'s captial city is called \(country.capitalCity.name)") // 打印"Canada's capital city is called Ottawa"
占有列表中的每个元素都是由weak或者unowned关键字和实例的引用,如:
[unowned self] // 无主引用 [weak self] // 弱引用
捕获列表放置在闭包参数列表和返回类型之前:
@lazy var someClosure: (Int, String) -> String = { [unowned self] (index: Int, stringToProcess: String) -> String in // closure body goes here }
如果闭包没有指定参数列表或者返回类型(可以通过上下文推断),那么占有列表放在闭包开始的地方,跟着是关键字in:
@lazy var someClosure: () -> String = { [unowned self] in // closure body goes here }
注意:
2015-03-24
21:15:57