Swift編程中用以管理內(nèi)存的自動(dòng)引用計(jì)數(shù)詳解
Swift 內(nèi)存管理功能是通過(guò)使用自動(dòng)引用計(jì)數(shù)(ARC)來(lái)處理。ARC用于初始化和取消初始化所述系統(tǒng)資源,從而釋放使用的類實(shí)例的存儲(chǔ)器空間當(dāng)實(shí)例不再需要。ARC跟蹤代碼的實(shí)例有效地管理存儲(chǔ)資源之間的關(guān)系的信息。
ARC的功能
- 在每一次一個(gè)新的類實(shí)例被創(chuàng)建時(shí)ARC分配一塊內(nèi)存以存儲(chǔ)信息 init()
- 關(guān)于實(shí)例類型和其值的信息存儲(chǔ)在存儲(chǔ)器中
- 當(dāng)類實(shí)例不再需要它自動(dòng)由 deinit() 釋放,用于進(jìn)一步類實(shí)例的存儲(chǔ)和檢索的存儲(chǔ)空間
- ARC保存在磁道當(dāng)前參照類實(shí)例的屬性,常量和變量,使得 deinit() 僅適用于那些不使用的實(shí)例。
- ARC維護(hù)“強(qiáng)引用”這些類實(shí)例屬性,常量和變量來(lái)限制釋放當(dāng)當(dāng)前的類實(shí)例正在使用。
ARC 程序
class StudDetails {
var stname: String!
var mark: Int!
init(stname: String, mark: Int) {
self.stname = stname
self.mark = mark
}
deinit {
println("Deinitialized \(self.stname)")
println("Deinitialized \(self.mark)")
}
}
let stname = "swift"
let mark = 98
println(stname)
println(mark)
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
swift 98
ARC 強(qiáng)參考周期類實(shí)例
class studmarks {
let name: String
var stud: student?
init (name: String) {
println("Initializing: \(name)")
self.name = name
}
deinit {
println("Deallocating: \(self.name)")
}
}
class student {
let name: String
var strname: studmarks?
init (name: String) {
println("Initializing: \(name)")
self.name = name
}
deinit {
println("Deallocating: \(self.name)")
}
}
var shiba: studmarks?
var mari: student?
shiba = studmarks(name: "Swift")
mari = student(name: "ARC")
shiba!.stud = mari
mari!.strname = shiba
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
Initializing: Swift Initializing: ARC
ARC弱和無(wú)主參考
Class類型屬性有兩種方法可以解決強(qiáng)引用周期:
- 弱引用
- 無(wú)主參考
這些引用是用來(lái)使一個(gè)實(shí)例指在一個(gè)基準(zhǔn)周期其他實(shí)例。然后實(shí)例可以為每一個(gè)實(shí)例參考代替處理強(qiáng)引用周期。當(dāng)用戶知道某些情況下可能會(huì)返回 'nil' 值,我們可能會(huì)指向使用弱引用。當(dāng)實(shí)例會(huì)返回不是零的東西,然后使用無(wú)主參考聲明。
弱引用程序
class module {
let name: String
init(name: String) { self.name = name }
var sub: submodule?
deinit { println("\(name) Is The Main Module") }
}
class submodule {
let number: Int
init(number: Int) { self.number = number }
weak var topic: module?
deinit { println("Sub Module with its topic number is \(number)") }
}
var toc: module?
var list: submodule?
toc = module(name: "ARC")
list = submodule(number: 4)
toc!.sub = list
list!.topic = toc
toc = nil
list = nil
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
ARC Is The Main Module Sub Module with its topic number is 4
無(wú)主參考程序
class student {
let name: String
var section: marks?
init(name: String) {
self.name = name
}
deinit { println("\(name)") }
}
class marks {
let marks: Int
unowned let stname: student
init(marks: Int, stname: student) {
self.marks = marks
self.stname = stname
}
deinit { println("Marks Obtained by the student is \(marks)") }
}
var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
ARC Marks Obtained by the student is 98
閉包強(qiáng)引用周期
當(dāng)我們分配一個(gè)閉包至類實(shí)例屬性,閉包的主體以捕獲特定實(shí)例強(qiáng)參考周期發(fā)生。強(qiáng)引用閉合由 self.someProperty 或 self.someMethod()定義。強(qiáng)引用周期用作閉包引用類型。
class HTMLElement {
let samplename: String
let text: String?
lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.samplename)>\(text)</\(self.samplename)>"
} else {
return "<\(self.samplename) />"
}
}
init(samplename: String, text: String? = nil) {
self.samplename = samplename
self.text = text
}
deinit {
println("\(samplename) is being deinitialized")
}
}
var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
println(paragraph!.asHTML())
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
<p>Welcome to Closure SRC</p>
弱和無(wú)主參考
當(dāng)閉包和實(shí)例相互引用,用戶可以定義在一個(gè)閉合作為無(wú)主引用捕獲。它不會(huì)允許用戶在同一時(shí)間解除分配實(shí)例。當(dāng)實(shí)例在某個(gè)時(shí)候返回一個(gè)“nil” 定義并使用弱實(shí)例的值。
class HTMLElement {
let module: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.module)>\(text)</\(self.module)>"
} else {
return "<\(self.module) />"
}
}
init(module: String, text: String? = nil) {
self.module = module
self.text = text
}
deinit {
println("\(module) the deinit()")
}
}
var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
println(paragraph!.asHTML())
paragraph = nil
當(dāng)我們使用 playground 運(yùn)行上面的程序,得到以下結(jié)果。
<Inside>ARC Weak References</Inside> Inside the deinit()
相關(guān)文章
switch循環(huán)所支持的數(shù)據(jù)類型案例分析
這篇文章主要介紹了switch循環(huán)所支持的數(shù)據(jù)類型,本文通過(guò)實(shí)際案例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Swift 3.0基礎(chǔ)學(xué)習(xí)之閉包
Swift引進(jìn)了閉包的概念,這個(gè)與object-c的block類似,使用過(guò)block的話都知道有多方便,所以開(kāi)始學(xué)Swift,先要把閉包學(xué)會(huì),后面使用會(huì)很頻繁。下面這篇文章主要介紹了Swift 3.0基礎(chǔ)學(xué)習(xí)之閉包的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-03-03Swift中的可選項(xiàng)Optional解包方式實(shí)現(xiàn)原理
這篇文章主要為大家介紹了Swift中的可選項(xiàng)Optional解包方式實(shí)現(xiàn)原理示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03