Sobes.tech
Intern

Wat is een garbage collector?

sobes.tech AI

Antwoord van AI

Op iOS is er geen traditionele garbage collector. In plaats daarvan wordt het mechanisme van Automatische Referentie Telling (ARC) gebruikt.

  • Automatisch mechanisme: ARC telt automatisch de sterke referenties naar objecten.
  • Vrijgave van geheugen: Wanneer het aantal sterke referenties naar een object nul bereikt, vrijgeeft ARC het toegewezen geheugen.
  • Voorkomen van geheugenlekken: Correct gebruik van sterke, zwakke en niet-eigenlijke (unowned) referenties helpt geheugenlekken en cycli in referenties te voorkomen.

Types referenties in ARC:

  • Sterk (strong): Verhoogt de referentieteller. Standaard.
  • Zwak (weak): Verhoogt de referentieteller niet. Wordt automatisch nil bij deallocatie van het object. Wordt gebruikt om cycli in sterke referenties te voorkomen. Wordt als optioneel type gedeclareerd.
  • Niet-eigen (unowned): Verhoogt de referentieteller niet. Het wordt gegarandeerd dat het object waarnaar wordt verwezen bestaat gedurende de volledige levensduur van de niet-eigenlijke referentie. Is niet optioneel. Wordt gebruikt wanneer twee objecten een wederzijdse sterke relatie hebben, maar één van hen een kortere levensduur heeft.

Voordelen van ARC:

  • Voorspelbaarheid: Geheugen vrijgave gebeurt deterministisch, zodra het object niet meer wordt gebruikt.
  • Prestaties: Er zijn geen extra kosten voor een achtergrond garbage collector, die pauzes kan veroorzaken.
  • Eenvoud: De ontwikkelaar hoeft het geheugen niet handmatig te beheren in de meeste gevallen, maar moet de principes van referentietelling begrijpen om geheugenlekken te voorkomen.

Voorbeeld van een cyclus van sterke referenties:

class Person {
    let name: String
    var apartment: Apartment? // sterke referentie naar Apartment

    init(name: String) { self.name = name }
    deinit { print("\(name) wordt gedeinitialiseerd") }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // zwakke referentie naar Person om cyclus te voorkomen

    init(unit: String) { self.unit = unit }
    deinit { print("Appartement \(unit) wordt gedeinitialiseerd") }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john // Het gebruik van weak hier is cruciaal

john = nil
unit4A = nil
// Zonder weak tenant: Zowel john als unit4A zouden niet gedeinitialiseerd worden.
// Met weak tenant: Zowel john als unit4A worden correct gedeinitialiseerd.