Sobes.tech
Middle

Vertel ons over het geheugenbeheer in iOS.

sobes.tech AI

Antwoord van AI

iOS gebruikt automatische referentietelling (ARC) voor geheugenbeheer. ARC vrijwaart automatisch objecten zodra er geen referenties meer naar hen zijn.

Belangrijke concepten:

  • Strong Reference: Verhoogt de referentieteller van een object. Het object wordt niet vrijgegeven zolang er sterke referenties naar zijn.
  • Weak Reference: Verhoogt de teller niet. Gebruikt om cycli van sterke referenties te voorkomen. Verwijst naar een object dat vrijgegeven kan worden. Als het object wordt vrijgegeven, wordt de weak referentie nil.
  • Unowned Reference: Vergelijkbaar met weak, verhoogt de teller niet. Gebruikt wanneer het object waarnaar wordt verwezen dezelfde of een langere levensduur heeft. Unowned referentie wordt niet nil bij vrijgave van het object. Toegang tot een vrijgegeven object via unowned resulteert in een runtime fout.

Cycli van sterke referenties (Retain Cycles): Ontstaan wanneer twee of meer objecten sterke referenties naar elkaar hebben, waardoor geen van beiden wordt vrijgegeven. Oplossingen zijn weak of unowned referenties.

Voorbeeld van een sterke referentiecircuit en de oplossing:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) wordt geïnitialiseerd")
    }

    deinit {
        print("\(name) wordt gedeinitialiseerd")
    }
}

class Apartment {
    let unit: String
    var tenant: Person? // Sterke referentie leidt tot retain cycle

    init(unit: String) {
        self.unit = unit
        print("Appartement \(unit) wordt geïnitialiseerd")
    }

    deinit {
        print("Appartement \(unit) wordt gedeinitialiseerd")
    }
}

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

john!.apartment = unit4A
unit4A!.tenant = john // Hier ontstaat een retain cycle

john = nil
unit4A = nil
// De initialisatiemethoden worden niet aangeroepen vanwege de retain cycle

Oplossing met weak:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) wordt geïnitialiseerd")
    }

    deinit {
        print("\(name) wordt gedeinitialiseerd")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Gebruik weak referentie om retain cycle te voorkomen

    init(unit: String) {
        self.unit = unit
        print("Appartement \(unit) wordt geïnitialiseerd")
    }

    deinit {
        print("Appartement \(unit) wordt gedeinitialiseerd")
    }
}

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

john!.apartment = unit4A
unit4A!.tenant = john

john = nil
unit4A = nil
// Beide objecten worden correct gedeinitialiseerd

Unowned vs Weak:

  • Gebruik weak wanneer de referentie nil kan worden (object kan als eerste worden vrijgegeven).
  • Gebruik unowned wanneer de referentie altijd een waarde zal hebben (het object waarnaar wordt verwezen heeft dezelfde of een langere levensduur).

Closures en cycli van referenties:

Closures kunnen referenties naar objecten vastleggen, wat cycli van sterke referenties creëert. Dit wordt opgelost met een capture list.

Voorbeeld:

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        [weak self] in // Capture self weakly
        guard let self = self else {
            return ""
        }
        var html = "<\(self.name)"
        if let text = self.text {
            html += ">\(text)</\(self.name)>"
        } else {
            html += " />"
        }
        return html
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) wordt gedeinitialiseerd")
    }
}

var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())

paragraph = nil
// Object wordt gedeinitialiseerd

Memory debugging:

  • Memory Graph Debugger: In Xcode visualiseert de verbindingen tussen objecten en identificeert cycli van sterke referenties.
  • Instruments (Allocations, Leaks): Hulpmiddelen voor het monitoren van geheugenallocatie en -vrijgave, en het opsporen van lekken.