Swift - ARC 概述
-
简述
内存管理功能及其使用通过自动引用计数 (ARC) 以 Swift 4 语言处理。ARC 用于初始化和取消初始化系统资源,从而在不再需要类实例时释放类实例使用的内存空间。ARC 跟踪有关我们代码实例之间关系的信息,以有效地管理内存资源。 -
ARC的功能
-
每次通过 init() 创建新的类实例时,ARC 都会分配一块内存来存储信息。
-
有关实例类型及其值的信息存储在内存中。
-
当不再需要类实例时,它会通过 deinit() 自动释放内存空间,以便进一步存储和检索类实例。
-
ARC 跟踪当前引用的类实例属性、常量和变量,以便 deinit() 仅应用于那些未使用的实例。
-
ARC 维护对那些类实例属性、常量和变量的“强引用”,以在当前使用类实例时限制释放。
-
-
ARC计划
class StudDetails { var stname: String! var mark: Int! init(stname: String, mark: Int) { self.stname = stname self.mark = mark } deinit { print("Deinitialized \(self.stname)") print("Deinitialized \(self.mark)") } } let stname = "Swift 4" let mark = 98 print(stname) print(mark)
当我们使用操场运行上述程序时,我们得到以下结果 -Swift 4 98
-
ARC 强引用循环类实例
class studmarks { let name: String var stud: student? init (name: String) { print("Initializing: \(name)") self.name = name } deinit { print("Deallocating: \(self.name)") } } class student { let name: String var strname: studmarks? init (name: String) { print("Initializing: \(name)") self.name = name } deinit { print("Deallocating: \(self.name)") } } var shiba: studmarks? var mari: student? shiba = studmarks(name: "Swift 4") mari = student(name: "ARC") shiba!.stud = mari mari!.strname = shiba
当我们使用操场运行上述程序时,我们得到以下结果 -Initializing: Swift 4 Initializing: ARC
-
ARC 弱引用和无主引用
类类型属性有两种解决强引用循环的方法 -- 弱引用
- 无主引用
这些引用用于使一个实例能够在引用循环中引用其他实例。然后实例可能会引用每个实例而不是关心强引用循环。当用户知道某个实例可能返回“nil”值时,我们可以使用弱引用来指出这一点。当实例要返回一些东西而不是 nil 时,然后用无主引用声明它。弱参考程序
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
无主参考程序
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()”定义。强引用循环用作闭包的引用类型。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()