Junior
Πώς λειτουργεί ο συλλέκτης απορριμμάτων (garbage collector);
sobes.tech AI
Απάντηση από AI
Στο πλαίσιο της ανάπτυξης iOS/macOS, η Swift/Objective-C δεν χρησιμοποιεί συλλέκτη απορριμμάτων (GC), αλλά αυτόματη καταμέτρηση αναφορών (Automatic Reference Counting, ARC).
Το ARC διαχειρίζεται αυτόματα τη μνήμη μετρώντας τον αριθμό των ισχυρών αναφορών (Strong) σε κάθε στιγμιότυπο κλάσης (και κλεισίματα με καταγραφή). Όταν ο μετρητής ισχυρών αναφορών φτάσει στο μηδέν, το σύστημα ελευθερώνει τη μνήμη που καταλαμβάνει το αντικείμενο.
Βασικά σημεία του ARC:
- Ισχυρές αναφορές (Strong): Αυξάνουν τον μετρητή αναφορών. Το αντικείμενο παραμένει στη μνήμη όσο έχει τουλάχιστον μία ισχυρή αναφορά.
- Αδύναμες αναφορές (Weak): Δεν αυξάνουν τον μετρητή αναφορών. Χρησιμοποιούνται για την αποφυγή κυκλικών αναφορών. Αναφέρονται προαιρετικά σε ένα αντικείμενο και γίνονται nil όταν το αντικείμενο απελευθερώνεται.
- Ανεξάρτητες αναφορές (Unowned): Δεν αυξάνουν τον μετρητή αναφορών. Χρησιμοποιούνται όταν γνωρίζουμε τον κύκλο ζωής των αντικειμένων και ένα αντικείμενο θα υπάρχει πάντα όσο υπάρχει ένα άλλο. Η αναφορά δεν είναι προαιρετική. Αν το αντικείμενο στο οποίο αναφέρεται ένα unowned απελευθερωθεί, η πρόσβαση σε αυτό θα προκαλέσει σφάλμα κατά την εκτέλεση.
Το ARC λειτουργεί κατά τη φάση της μεταγλώττισης, εισάγοντας κλήσεις σε retain (αύξηση μετρητή) και release (μείωση μετρητή) στον αντίστοιχο κώδικα.
class MyClass {
var prop: String = ""
}
var reference1: MyClass? = MyClass() // Μετρητής = 1
var reference2 = reference1 // Μετρητής = 2
reference1 = nil // Μετρητής = 1
reference2 = nil // Μετρητής = 0, το αντικείμενο απελευθερώνεται
class Person {
let name: String
weak var apartment: Apartment? // Αδύναμη αναφορά για αποφυγή κυκλικών αναφορών
init(name: String) { self.name = name; print("\(name) αρχίζει") }
deinit { print("\(name) αποδεσμεύεται") }
}
class Apartment {
let unit: String
unowned var tenant: Person // Μη-κατοχυρωμένη αναφορά
init(unit: String, tenant: Person) { self.unit = unit; self.tenant = tenant; print("Διαμέρισμα \(unit) αρχίζει") }
deinit { print("Διαμέρισμα \(unit)) αποδεσμεύεται") }
}