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()