Junior
Jak działa zbieracz śmieci?
sobes.tech AI
Odpowiedź od AI
W kontekście rozwoju iOS/macOS, Swift/Objective-C nie używa zbieracza śmieci (GC), lecz automatycznego zliczania odwołań (Automatic Reference Counting, ARC).
ARC automatycznie zarządza pamięcią, zliczając liczbę silnych odwołań do każdej instancji klasy (oraz zamknięć z przechwytem). Gdy licznik silnych odwołań osiąga zero, system zwalnia pamięć zajmowaną przez obiekt.
Kluczowe punkty ARC:
- Silne odwołania (Strong): Zwiększają licznik odwołań. Obiekt pozostaje w pamięci, dopóki ma co najmniej jedno silne odwołanie.
- Słabe odwołania (Weak): Nie zwiększają licznika odwołań. Używane są do unikania cykli silnych odwołań. Odwołują się opcjonalnie do obiektu, który staje się nil, gdy obiekt zostanie zwolniony.
- Nieposiadane odwołania (Unowned): Nie zwiększają licznika odwołań. Używane, gdy znany jest cykl życia obiektów i jeden obiekt zawsze będzie istniał, dopóki inny istnieje. Odwołanie nie jest opcjonalne. Jeśli obiekt, na który się odwołuje unowned, zostanie zwolniony, dostęp do niego spowoduje błąd w czasie wykonywania.
ARC działa na etapie kompilacji, wstawiając wywołania retain (zwiększenie licznika) i release (zmniejszenie licznika) w odpowiednim kodzie.
class MyClass {
var prop: String = ""
}
var reference1: MyClass? = MyClass() // Licznik = 1
var reference2 = reference1 // Licznik = 2
reference1 = nil // Licznik = 1
reference2 = nil // Licznik = 0, obiekt jest zwalniany
class Person {
let name: String
weak var apartment: Apartment? // Słabe odwołanie, aby uniknąć cyklu
init(name: String) { self.name = name; print("\(name) jest inicjalizowany") }
deinit { print("\(name) jest deinitializowany") }
}
class Apartment {
let unit: String
unowned var tenant: Person // Nieposiadane odwołanie
init(unit: String, tenant: Person) { self.unit = unit; self.tenant = tenant; print("Mieszkanie \(unit) jest inicjalizowane") }
deinit { print("Mieszkanie \(unit) jest deinitializowane") }
}