Sobes.tech
Middle

Meséljen az iOS memória kezeléséről.

sobes.tech MI

Válasz az MI-től

Az iOS automatikus hivatkozásszámlálást (ARC) használ a memória kezelésére. Az ARC automatikusan felszabadítja az objektumokat, amint már nem hivatkoznak rájuk.

Fő fogalmak:

  • Erős Hivatkozás: Növeli egy objektum hivatkozásszámát. Az objektum nem kerül felszabadításra, amíg vannak erős hivatkozások rá.
  • Gyenge Hivatkozás: Nem növeli a hivatkozásszámot. Használják ciklusok elkerülésére. Egy objektumra mutat, amely felszabadulhat. Ha az objektum felszabadul, a gyenge hivatkozás nil lesz.
  • Unowned Hivatkozás: Hasonló a gyenge hivatkozáshoz, nem növeli a hivatkozásszámot. Akkor használják, amikor a hivatkozott objektum ugyanannyi vagy hosszabb élettartamú. Az unowned hivatkozás nem lesz nil a felszabaduláskor. Hozzáférés egy felszabadult objektumhoz futási időben hibát eredményez.

Erős ciklusok (Retain Cycles): Akkor fordulnak elő, amikor két vagy több objektum erős hivatkozásokat tart fenn egymásra, megakadályozva azok felszabadulását. Gyenge vagy unowned hivatkozásokkal oldhatók meg.

Példa erős ciklusra és megoldása:

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

    init(name: String) {
        self.name = name
        print("\(name) inicializálva")
    }

    deinit {
        print("\(name) deinitializálva")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Gyenge hivatkozás a ciklus elkerülése érdekében

    init(unit: String) {
        self.unit = unit
        print("Lakás \(unit) inicializálva")
    }

    deinit {
        print("Lakás \(unit) deinitializálva")
    }
}

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

john!.apartment = unit4A
unit4A!.tenant = john // Itt ciklus keletkezik

john = nil
unit4A = nil
// A deinitializálási metódusok nem hívódnak meg a ciklus miatt

Megoldás gyenge hivatkozással:

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

    init(name: String) {
        self.name = name
        print("\(name) inicializálva")
    }

    deinit {
        print("\(name) deinitializálva")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Gyenge hivatkozás a ciklus elkerülése érdekében

    init(unit: String) {
        self.unit = unit
        print("Lakás \(unit) inicializálva")
    }

    deinit {
        print("Lakás \(unit) deinitializálva")
    }
}

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

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

john = nil
unit4A = nil
// Mindkét objektum helyesen deinitializálódik

unowned vs weak:

  • Használd a weak-et, amikor a hivatkozás nil-vé válhat (az objektum elsőként szabadulhat fel).
  • Használd az unowned-et, amikor a hivatkozás mindig értéket fog tartalmazni (az objektum, amelyre hivatkozik, ugyanannyi vagy hosszabb élettartamú).

Closures és ciklusok:

A closures képesek objektumokra hivatkozni, így ciklusokat hozhatnak létre. Ezt a capture list segítségével lehet megoldani.

Példa:

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

    lazy var asHTML: () -> String = {
        [weak self] in // Gyenge capture
        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) deinitializálva")
    }
}

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

paragraph = nil
// Az objektum deinitializálódik

Memória hibák hibakeresése:

  • Memory Graph Debugger: Az Xcode lehetővé teszi az objektumok közötti kapcsolatok vizualizálását és a ciklusok azonosítását.
  • Instruments (Allocations, Leaks): Eszközök a memória allokációk és felszabadítások nyomon követésére, valamint a szivárgások felderítésére.