- Swift 教程
- Swift - 首頁
- Swift - 概述
- Swift - 環境
- Swift - 基本語法
- Swift - 變數
- Swift - 常量
- Swift - 字面量
- Swift - 註釋
- Swift 運算子
- Swift - 運算子
- Swift - 算術運算子
- Swift - 比較運算子
- Swift - 邏輯運算子
- Swift - 賦值運算子
- Swift - 位運算子
- Swift - 其他運算子
- Swift 高階運算子
- Swift - 運算子過載
- Swift - 算術溢位運算子
- Swift - 恆等運算子
- Swift - 範圍運算子
- Swift 資料型別
- Swift - 資料型別
- Swift - 整數
- Swift - 浮點數
- Swift - Double
- Swift - 布林值
- Swift - 字串
- Swift - 字元
- Swift - 類型別名
- Swift - 可選型別
- Swift - 元組
- Swift - 斷言和前提條件
- Swift 控制流
- Swift - 決策
- Swift - if 語句
- Swift - if...else if...else 語句
- Swift - if-else 語句
- Swift - 巢狀 if 語句
- Swift - switch 語句
- Swift - 迴圈
- Swift - for in 迴圈
- Swift - while 迴圈
- Swift - repeat...while 迴圈
- Swift - continue 語句
- Swift - break 語句
- Swift - fall through 語句
- Swift 集合
- Swift - 陣列
- Swift - 集合
- Swift - 字典
- Swift 函式
- Swift - 函式
- Swift - 巢狀函式
- Swift - 函式過載
- Swift - 遞迴
- Swift - 高階函式
- Swift 閉包
- Swift - 閉包
- Swift - 轉義和非轉義閉包
- Swift - 自動閉包
- Swift 面向物件程式設計
- Swift - 列舉
- Swift - 結構體
- Swift - 類
- Swift - 屬性
- Swift - 方法
- Swift - 下標
- Swift - 繼承
- Swift - 重寫
- Swift - 初始化
- Swift - 析構
- Swift 高階
- Swift - ARC 概述
- Swift - 可選鏈
- Swift - 錯誤處理
- Swift - 併發
- Swift - 型別轉換
- Swift - 巢狀型別
- Swift - 擴充套件
- Swift - 協議
- Swift - 泛型
- Swift - 訪問控制
- Swift - 函式與方法
- Swift - SwiftyJSON
- Swift - 單例類
- Swift 隨機數
- Swift 不透明型別和裝箱型別
- Swift 有用資源
- Swift - 線上編譯
- Swift - 快速指南
- Swift - 有用資源
- Swift - 討論
Swift - ARC 概述
Swift 中的自動引用計數
自動引用計數 (ARC) 是 Swift 使用的一種記憶體管理機制,它自動跟蹤和管理物件的記憶體分配和釋放。或者我們可以說它用於初始化和反初始化系統資源,從而在不再需要類例項時釋放類例項使用的記憶體空間。它跟蹤例項之間關係的資訊,以有效地管理記憶體資源。ARC 通常僅適用於類的例項,因為它們是引用型別。
ARC 的工作原理
每當透過 init() 建立新的類例項時,ARC 都會分配一塊記憶體來儲存資訊。
例項型別及其值的相關資訊儲存在記憶體中。
當不再需要類例項時,它會透過 deinit() 自動釋放記憶體空間,以便進一步儲存和檢索類例項。
ARC 跟蹤當前引用的類例項屬性、常量和變數,以便僅對未使用的例項應用 deinit()。
ARC 對這些類例項屬性、常量和變數保持“強引用”,以限制在類例項當前正在使用時進行釋放。
示例
演示 ARC 的 Swift 程式。
class StudDetails {
// Properties
var stname: String
var mark: Int
// Initializer to initialize instances of the class
init(stname: String, mark: Int) {
self.stname = stname
self.mark = mark
}
// Deinitializer to deinitialize the instances of
// the class when they are no longer required
deinit {
print("Deinitialized \(self.stname)")
print("Deinitialized \(self.mark)")
}
}
// Creating class instance
var obj1 = StudDetails( stname:"Swift", mark:98)
// Creating another class instance
var obj2: StudDetails? = StudDetails(stname: "iOS", mark: 95)
// Setting anotherObj to nil to deallocate the memory
obj2 = nil
輸出
它將產生以下輸出:
Deinitialized iOS Deinitialized 95
Swift 中類例項之間的強引用迴圈
ARC 用於透過跟蹤物件引用來自動管理記憶體。但是,開發人員面臨著一個挑戰,那就是建立強引用迴圈,其中兩個或多個物件相互強引用,這會阻止它們的引用計數達到零,並且由於此原因會導致記憶體洩漏。
示例
演示 Swift 中類例項之間強引用迴圈的 Swift 程式。
class studmarks {
let name: String
var stud: student?
// Initializer
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
// Deinitializer
deinit {
print("Deallocating: \(self.name)")
}
}
class student {
let name: String
var strname: studmarks?
// Initializer
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
// Deinitializer
deinit {
print("Deallocating: \(self.name)")
}
}
// Declare optional variables for instances
var shiba: studmarks?
var mari: student?
shiba = studmarks(name: "Swift 4")
mari = student(name: "ARC")
// Create a strong reference cycle by assigning references to each other
shiba!.stud = mari
mari!.strname = shiba
輸出
它將產生以下輸出:
Initializing: Swift 4 Initializing: ARC
為了解決強引用迴圈,Swift 提供了弱引用和無主引用。這些引用用於使一個例項能夠引用引用迴圈中的其他例項。然後,例項可以引用每個例項,而不必關心強引用迴圈。
弱引用
它對物件的引用是可選的,並且不會對該物件進行強引用。當它引用的物件被釋放時,它將返回 nil。它通常用於引用的物件的生命週期不保證比引用物件持續時間更長的情況。它通常用於引用的物件可以獨立釋放的關係。我們可以使用weak關鍵字宣告弱引用。
語法
以下是弱引用的語法:
class Class1 {
var name: Name?
}
class Name {
weak var teacher: Class1?
}
示例
演示弱引用的 Swift 程式。
class module {
let name: String
init(name: String) { self.name = name }
var sub: submodule?
deinit { print("\(name) Is The Main Module") }
}
class submodule {
let number: Int
init(number: Int) { self.number = number }
weak var topic: module?
deinit { print("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
輸出
它將產生以下輸出:
ARC Is The Main Module Sub Module with its topic number is 4
無主引用
與弱引用相比,它對物件的引用是非可選的,並且不會對該物件進行強引用。它假設引用物件永遠不會變成 nil,而引用物件仍然存在。它通常用於您知道引用的物件的生命週期至少與引用物件的生命週期一樣長的情況。它通常用於引用的物件與引用物件具有相同或更長的生命週期的關係。我們可以使用unowned關鍵字宣告無主引用。
語法
以下是無主引用的語法:
class Class1 {
var name: Name?
}
class Name {
unowned var teacher: Class1
}
示例
演示無主引用的 Swift 程式。
class student {
let name: String
var section: marks?
init(name: String) {
self.name = name
}
deinit { print("\(name)") }
}
class marks {
let marks: Int
unowned let stname: student
init(marks: Int, stname: student) {
self.marks = marks
self.stname = stname
}
deinit { print("Marks Obtained by the student is \(marks)") }
}
var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil
輸出
它將產生以下輸出:
ARC Marks Obtained by the student is 98
閉包的強引用迴圈
當我們將閉包分配給類例項屬性並將閉包的主體捕獲特定例項時,可能會發生強引用迴圈。對閉包的強引用由“self.someProperty”或“self.someMethod()”定義。強引用迴圈用作閉包的引用型別。
示例
演示閉包的強引用迴圈的 Swift 程式。
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 {
print("\(samplename) is being deinitialized")
}
}
var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
print(paragraph!.asHTML())
輸出
它將產生以下輸出:
<p>Welcome to Closure SRC</p>
解決閉包的強引用迴圈
我們可以使用弱引用和無主引用來解決閉包的強引用迴圈。當閉包和例項相互引用時,使用者可以將閉包中的捕獲定義為無主引用。然後它將不允許使用者同時釋放例項。當例項有時返回“nil”值時,請使用弱例項定義該閉包。
示例
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 {
print("\(module) the deinit()")
}
}
var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
print(paragraph!.asHTML())
paragraph = nil
輸出
它將產生以下輸出:
<Inside>ARC Weak References</Inside> Inside the deinit()