Sobes.tech
Middle

Na czym polega różnica między zbieraczem śmieci (garbage collector) a automatycznym zarządzaniem pamięcią (ARC)?

sobes.tech AI

Odpowiedź od AI

Zbieracz śmieci automatycznie znajduje i zwalnia pamięć, która nie jest już używana przez program. Działa w tle, okresowo skanując stertę i identyfikując obiekty, na które nie ma aktywnych odwołań.

ARC (Automatyczne Liczenie Referencji) w Swift i Objective-C zarządza życiem obiektów, zliczając liczbę silnych odwołań do każdego obiektu. Gdy liczba silnych odwołań do obiektu osiąga zero, ARC automatycznie zwalnia pamięć zajmowaną przez ten obiekt.

Główne różnice:

Cecha Zbieracz śmieci ARC
Zasada działania Szukanie obiektów niedostępnych Liczenie silnych odwołań
Moment zwolnienia Niejednoznaczny, podczas skanowania Deterministyczny, gdy licznik osiąga 0
Dodatkowe koszty Pauzy podczas wykonywania programu (podczas zbierania) Minimalne, podczas zmiany licznika
Prognozowalność Niska Wysoka
Odwołania cykliczne Wymagają specjalnych podejść (np. słabe odwołania) Wymagają użycia weak lub unowned odwołań
Użycie w iOS Nieobecne w nowoczesnym Objective-C i Swift Główny mechanizm zarządzania pamięcią w Objective-C i Swift

Przykład użycia weak do zapobiegania cyklom silnych odwołań w ARC:

class Person {
    let name: String
    var apartment: Apartment? // silne odwołanie

    init(name: String) {
        self.name = name
        print("\(name) jest inicjalizowany")
    }
    deinit {
        print("\(name) jest deinitializowany")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // słabe odwołanie

    init(unit: String) {
        self.unit = unit
        print("Mieszkanie \(unit) jest inicjalizowane")
    }
    deinit {
        print("Mieszkanie \(unit) jest deinitializowane")
    }
}

var john: Person?
var unit4A: Apartment?

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

john!.apartment = unit4A
unit4A!.tenant = john // słabe odwołanie zapobiega cyklowi zatrzymania

john = nil // obiekt Person jest deinitializowany
unit4A = nil // obiekt Apartment jest deinitializowany