Sobes.tech
Intern

Kas yra šiukšlių surinkėjas (garbage collector)?

sobes.tech AI

Atsakymas iš AI

iOS nėra tradicinio atminties surinkėjo. Vietoje jo naudojamas Automatic Reference Counting (ARC) mechanizmas.

  • Automatinis mechanizmas: ARC automatiškai skaičiuoja stipriąsias nuorodas į objektus.
  • Atminties laisvavimas: Kai stipriųjų nuorodų skaičius pasiekia nulį, ARC atlaisvina paskirtą atmintį.
  • Užkertant kelią nutekėjimams: Tinkamas stipriųjų, silpnųjų ir neapibrėžtųjų (unowned) nuorodų naudojimas leidžia išvengti atminties nutekėjimo ir stipriųjų nuorodų ciklų.

ARC nuorodų tipai:

  • Stipri (strong): Padidina nuorodų skaitiklį. Pagal numatytuosius nustatymus.
  • Silpna (weak): Nepadidina nuorodų skaitiklio. Automatiškai tampa nil objekto dealloc metu. Naudojama stipriųjų nuorodų ciklų išvengimui. Deklaruojama kaip pasirinktinio tipo.
  • Nepriklausoma (unowned): Nepadidina nuorodų skaitiklio. Garantuoja, kad objektas, į kurį ji nurodo, egzistuoja viso gyvavimo ciklo metu. Nėra pasirinktinė. Naudojama, kai du objektai turi tarpusavio stiprią ryšį, bet vienas iš jų turi trumpesnį gyvavimo ciklą.

ARC privalumai:

  • Numatymas: Atminties laisvavimas vyksta deterministiškai, kai tik objektas nebepanaudojamas.
  • Našumas: Nėra papildomų išlaidų foniniam atminties surinkėjui, kuris gali sukelti pauzes.
  • Paprastumas: Kūrėjas neturi rankiniu būdu valdyti atminties daugeliu atvejų, bet turi suprasti nuorodų skaičiavimo principus, kad išvengtų nutekėjimų.

Pavyzdys stipriųjų nuorodų ciklo:

class Person {
    let name: String
    var apartment: Apartment? // stipri nuoroda į Apartment

    init(name: String) { self.name = name }
    deinit { print("\(name) yra išlaisvintas") }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // silpna nuoroda į Person, siekiant išvengti ciklo

    init(unit: String) { self.unit = unit }
    deinit { print("Apartment \(unit) yra išlaisvintas") }
}

var john: Person?
var unit4A: Apartment?

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

john!.apartment = unit4A
unit4A!.tenant = john // Naudojama weak, tai labai svarbu

john = nil
unit4A = nil
// Be weak tenant: Abu john ir unit4A nebūtų išlaisvinti.
// Su weak tenant: Abu john ir unit4A yra teisingai išlaisvinti.