1. 析構(gòu)函數(shù)基本概念
對(duì)象的內(nèi)存被回收前夕被隱式調(diào)用的方法, 對(duì)應(yīng)OC的
dealloc
方法主要執(zhí)行一些額外操作, 例如釋放一些持有資源, 關(guān)閉文件, 斷開(kāi)網(wǎng)絡(luò), 移除通知監(jiān)聽(tīng)者等
-
Swift 會(huì)自動(dòng)釋放不再需要的實(shí)例以釋放資源
- Swift 通過(guò)自動(dòng)引用計(jì)數(shù)(ARC)處理實(shí)例的內(nèi)存管理
- 當(dāng)引用計(jì)數(shù)為0時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)(不可以手動(dòng)調(diào)用)
-
**注意: **
- 需要手動(dòng)將一個(gè)對(duì)象釋放, 則只要將其指向
nil
就可 - 指向
nil
表示沒(méi)有了強(qiáng)引用, 然而在 Swift 中nil
也是一個(gè)類(lèi), - 因此在定義對(duì)象的時(shí)候, 必須定義是變量
var
, 并且是可選類(lèi)型?
, 只有可選類(lèi)型才可以賦值為nil
- 需要手動(dòng)將一個(gè)對(duì)象釋放, 則只要將其指向
析構(gòu)函數(shù)的寫(xiě)法
deinit {
// 執(zhí)行析構(gòu)過(guò)程
}
- 示例
class Person {
var name : String
var age : Int
init(name : String, age : Int) {
self.name = name
self.age = age
}
deinit {
print("Person-deinit")
}
}
//指向 nil 表示沒(méi)有了強(qiáng)引用, 然而在 Swift 中 nil 也是一個(gè)類(lèi),
//因此在定義對(duì)象的時(shí)候, 必須定義為變量 var, 并且是可選類(lèi)型
var p : Person? = Person(name: "cdc", age: 18)
p = nil
// 輸出結(jié)果: Person-deinit
class FileHandler{
var fd: Int32? //文件描述符
//指定構(gòu)造器
init(path:String){
//需要打開(kāi)的文件路徑, 打開(kāi)方式(只讀)
//open方法是UNIX的方法
let ret = open(path, O_RDONLY)
if ret == -1{
fd = nil
}else{
fd = ret
}
print("對(duì)象被創(chuàng)建")
}
//析構(gòu)方法
deinit{
//關(guān)閉文件
if let ofd = fd{
close(ofd)
}
print("對(duì)象被銷(xiāo)毀")
}
}
var fh:FileHandler? =
FileHandler(path:"/Users/chendehao/Desktop/chendehao.jpg")
//當(dāng)對(duì)象沒(méi)有任何強(qiáng)引用時(shí)會(huì)被銷(xiāo)毀
fh = nil
//輸出結(jié)果:
//對(duì)象被創(chuàng)建
//對(duì)象被銷(xiāo)毀
2. 析構(gòu)函數(shù)的自動(dòng)繼承
- 父類(lèi)的析構(gòu)方法會(huì)被自動(dòng)調(diào)用, 不需要子類(lèi)管理
- 析構(gòu)函數(shù)的調(diào)用順序, 實(shí)現(xiàn)調(diào)用子類(lèi), 在調(diào)用父類(lèi)
// 父類(lèi)
class Person {
var name:String
init(name:String){
self.name = name
print("Person init")
}
deinit{
print("Person deinit")
}
}
// 子類(lèi)
class SuperMan: Person {
var age:Int
init(age:Int){
self.age = age
super.init(name: "cdh")
print("SuperMan init")
}
deinit{
//如果父類(lèi)的析構(gòu)方法不會(huì)被自動(dòng)調(diào)用,那么我們還需要關(guān)心父類(lèi)
//但是如果這樣做對(duì)子類(lèi)是比較痛苦的
print("SuperMan deinit")
}
}
var sm: SuperMan? = SuperMan(age: 20)
sm = nil
//輸出結(jié)果:
//Person init // 先是父類(lèi)被初始話(huà)
//SuperMan init // 子類(lèi)被初始化
//SuperMan deinit // 先是子類(lèi)被釋放
//Person deinit // 父類(lèi)被釋放