Swift-内存管理

来源:互联网 发布:c语言高级 编辑:程序博客网 时间:2024/05/16 06:57

//内存管理/自动引用计数/弱引用/非持有引用

 

//引用计数:每个对象都有一个引用计数,用来记录有多少人(对象或变量)需要该对象活着

//当引用计数>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//Jackcard指向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

0 0
原创粉丝点击