Swift ARC概述

Swift ARC概述

内存管理函数及其使用是通过自动引用计数(ARC)来处理Swift 4语言中的。ARC用于初始化和反初始化系统资源,从而在不再需要实例时释放类实例使用的内存空间。ARC会跟踪有关代码实例之间关系的信息,以有效管理内存资源。

ARC的功能

  • 每当通过init()创建一个新的类实例时,ARC会分配一块内存来存储信息。

  • 实例类型及其值的信息存储在内存中。

  • 当不再需要该类实例时,ARC会自动释放内存空间以供进一步的类实例存储和检索。

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

当我们使用playground运行上述程序时,我们将获得以下结果−

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

当我们使用playground运行上面的程序时,我们得到以下结果 –

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

当我们在playground上运行上面的程序时,我们得到以下结果 –

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

当我们在playground上运行上面的程序时,我们得到以下结果 –

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

当我们在playground中运行以上程序时,我们得到以下结果 –

<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

当我们在playground上运行以上程序时,我们得到以下结果 −

<Inside>ARC Weak References</Inside>
Inside the deinit()

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程