//内存管理/自动引用计数/弱引用/非持有引用
//引用计数:每个对象都有一个引用计数,用来记录有多少人(对象或变量)需要该对象活着
//当引用计数>0的时候,该对象会保留在内存中
//当引用计数=0的时候,该对象会立刻从内存中销毁
//自动引用计数不等于垃圾回收机制,垃圾回收机制是内存使用特别大/紧缺时,会检查各种结构(比如堆栈)、对象,在需要清理时给予清理
//弱引用不会增加引用计数: weak var xxx
//弱引用一定是可能值类型
//对可能值进行绑定会产生一个强引用,如下
//if letperson = apt.person {
// person.dingDong()
//}
//person就是一个指向apt.person的强引用,该强引用在if{}结束后销毁
//可能值链也会产生强引用,只在所在行生效,不会保存到下一行,如下
//apt.person?.dingDong
//apt.person?.greet()
//强引用:一般的指向对象的变量都是强引用,比如:局部变量,对象属性
//弱引用或非持有引用:当引用需要反向指回时,如果还使用强引用会产生引用回路,从而内存泄露。
//引用计数只引用在类的实例。结构体和枚举是值类型,不是引用类型,不是以引用的方式来存储和传递的。
//=============================================
// Person&Apartment的例子
//是两个属性都可以是nil,这种场景适合使用弱引用
//=============================================
class Person {
let name: String
weak varapartment : Apartment?
init(name: String){ self.name= name }
deinit { println("\(name) is beingdeinitialized") }
}
class Apartment {
let number: Int
var name = "Qs"
weak var tenant: Person? = nil
init(number: Int){ self.number= number }
deinit { println("Apartment #\(number) is beingdeinitialized") }
}
var john: Person?
var number73: Apartment?
john = Person(name:"John Qiu")
number73 = Apartment(number: 73)
john?.apartment = number73
number73?.tenant = john
let name1 = john!.apartment!.name
let name2 = john?.apartment?.name
number73?.tenant = nil
number73?.tenant
//无主引用:ZZ称非持有引用,JKXY称无主引用
//无主引用始终有值,不会为nil,只能定义为非可选类型,可以直接使用,不用解析(!)
//同生命线的关系
//===========================================
// Customer&CreditCard的例子
//是一个属性是nil,另外一个属性不允许是nil
//这种场景适合使用无主引用
//===========================================
class Customer {
let name: String
var card: CreditCard?
init(name: String){
self.name= name
println("\(name) is beinginitialized")
}
deinit { println("\(name) is beingdeinitialized") }
}
class CreditCard {
let number: Int
unowned letcustomer: Customer
init(number: Int,customer: Customer) {
self.number= number
self.customer= customer
println("Card #\(self.number) is beinginitialized")
}
deinit{ println("Card #\(self.number) is beingdeinitialized") }
}
var Tom: Customer?
var ICard: CreditCard
Tom = Customer(name:"Tom Qiu")
Tom!.card = CreditCard(number: 9558801,customer: Tom!) // "Tom!"用于作为实参的初始化参数必须要是确定值,不能是可能值,否则报错
ICard = CreditCard(number:9558802, customer: Tom!)
Tom?.card = ICard
Tom?.card
var Jack: Customer?
var ICard1: CreditCard?
Jack = Customer(name: "Jack Qiu") //Jack Qiu is being initialized
ICard1 = CreditCard(number: 9558803, customer: Jack!) //Card #9558803 is being initialized
//"Jack!"实参的初始化参数必须要是确定值,不能是可能值,否则报错
Jack!.card = ICard1 //Jack的card指向9558803
Jack?.card = CreditCard(number: 9558804,customer: Jack!) // "Jack!"用于作为实参的初始化参数必须要是确定值,不能是可能值,否则报错
println(Jack!.card!.customer.name)//customer可以直接用,不用加!
Jack = nil //Jack Qiu is being deinitialized Card #9558804 is beingdeinitialized
ICard1 = nil //Card #9558803 is being deinitialized
//无主引用以及隐式解析可选属性
//===========================================
//Country&City的例子
//是两个属性都必须有值,且初始化完成后不能为nil
//这种场景需要使用无主引用+隐式解析可选属性
//===========================================
class Country {
let name: String
let capitalCity: City! //隐式解析可选属性,如果这里用?,则后续调用需要强制解析
init(name: String,capitalName: String) {
self.name= name
self.capitalCity = City(name: capitalName, country: self) //Country的实例完全初始化后才能将self送给City的初始化函数,因此
}
deinit {
println("Countrydestroy")
}
}
class City {
let name: String
unowned letcountry: Country
init(name: String,country: Country) {
self.name= name
self.country= country
}
deinit {
println("Citydestroy")
}
}
var canada = Country(name:"Canada", capitalName: "Ottawa")
println("\(canada.name)'s capital city is called \(canada.capitalCity.name)")
//如果Country定义非隐式解析可选属性:let capitalCity: City? 则如下使用
//println("\(canada.name)'scapital city is called \(canada.capitalCity!.name)")
//********************捕获列表*********************
//************************************************
//类内方法嵌套闭包时,小心引用回路
//关键字:[unowned/weak self/instance],
//格式:放在闭包参数前
//varsomeClosure: (Int, String) -> String = {
// [unowned self](index: Int, stringToProcess: String) in
// return " HAHA "
//}
//************************************************
class HTMLElement {
let name: String
let text: String?
//下面用到捕获列表
lazy varasHtml: () -> String = {
[unowned self] in
if lettext = self.text{
return "\(self.name) + \(self.text!)"
} else {
return " \(self.name) "
}
}
init(name: String,text: String? = nil){
self.name= name
self.text= text
}
deinit {
println("\(name) destroy")
}
}
var paragraph : HTMLElement?= HTMLElement(name: "HTName",text: "HTText")
println(paragraph!.asHtml())
paragraph = nil