Swift - ARC Übersicht

Speicherverwaltungsfunktionen und deren Verwendung werden in der Sprache Swift 4 durch automatische Referenzzählung (ARC) behandelt. ARC wird zum Initialisieren und Deinitialisieren der Systemressourcen verwendet, wodurch Speicherplätze freigegeben werden, die von den Klasseninstanzen verwendet werden, wenn die Instanzen nicht mehr benötigt werden. ARC verfolgt Informationen über die Beziehungen zwischen unseren Code-Instanzen, um die Speicherressourcen effektiv zu verwalten.

Funktionen von ARC

  • ARC weist einen Speicherblock zu, um die Informationen jedes Mal zu speichern, wenn eine neue Klasseninstanz von init () erstellt wird.

  • Informationen über den Instanztyp und seine Werte werden gespeichert.

  • Wenn die Klasseninstanz nicht mehr benötigt wird, gibt sie automatisch den Speicherplatz durch deinit () für das weitere Speichern und Abrufen von Klasseninstanzen frei.

  • ARC verfolgt die aktuell verweisenden Eigenschaften, Konstanten und Variablen von Klasseninstanzen, sodass deinit () nur auf diese nicht verwendeten Instanzen angewendet wird.

  • ARC behält einen 'starken Verweis' auf diese Klasseninstanzeigenschaften, Konstanten und Variablen bei, um die Freigabe zu beschränken, wenn die Klasseninstanz derzeit verwendet wird.

ARC-Programm

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)

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

Swift 4
98

Klasseninstanzen für starke ARC-Referenzzyklen

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

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

Initializing: Swift 4
Initializing: ARC

ARC Schwache und nicht besessene Referenzen

Klassentyp-Eigenschaften bieten zwei Möglichkeiten, um starke Referenzzyklen aufzulösen:

  • Schwache Referenzen
  • Nicht besessene Referenzen

Diese Referenzen werden verwendet, damit eine Instanz andere Instanzen in einem Referenzzyklus referenzieren kann. Dann können sich die Instanzen auf jede einzelne Instanz beziehen, anstatt sich um einen starken Referenzzyklus zu kümmern. Wenn der Benutzer weiß, dass eine Instanz möglicherweise 'Null'-Werte zurückgibt, können wir darauf hinweisen, dass eine schwache Referenz verwendet wird. Wenn die Instanz etwas zurückgibt und nicht Null, deklarieren Sie es mit einem nicht besessenen Verweis.

Schwaches Referenzprogramm

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

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

ARC Is The Main Module
Sub Module with its topic number is 4

Nicht besessenes Referenzprogramm

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

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

ARC
Marks Obtained by the student is 98

Starke Referenzzyklen für Verschlüsse

Wenn wir der Klasseninstanzeigenschaft und dem Hauptteil der Schließung einen Abschluss zuweisen, um eine bestimmte Instanz zu erfassen, kann ein starker Referenzzyklus auftreten. Ein starker Verweis auf den Abschluss wird durch 'self.someProperty' oder 'self.someMethod ()' definiert. Starke Referenzzyklen werden als Referenztypen für die Verschlüsse verwendet.

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

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

<p>Welcome to Closure SRC</p>

Schwache und nicht besessene Referenzen

Wenn sich der Abschluss und die Instanz aufeinander beziehen, kann der Benutzer die Erfassung in einem Abschluss als nicht besessene Referenz definieren. Dann würde es dem Benutzer nicht erlauben, die Instanz gleichzeitig freizugeben. Wenn die Instanz irgendwann einen 'Null'-Wert zurückgibt, definieren Sie den Abschluss mit der schwachen Instanz.

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

Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:

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