Ҳисобкунии худкории пайвандҳо чист?
sobes.tech AI
Ҷавоб аз AI
Автоматичното броене на референции (Automatic Reference Counting, ARC) е механизъм за управление на паметта в Swift и Objective-C, който автоматично следи и освобождава паметта, заделена за обекти. Всеки екземпляр на класа има брояч на референциите, който се увеличава при създаване на силна референция към обекта и се намалява при нейното премахване. Когато броячът достигне нула, ARC автоматично освобождава обекта и паметта, която заема.
ARC предотвратява течове на памет и дублирано освобождаване, опростявайки управлението на паметта в сравнение с ръчното управление (например в Objective-C без ARC).
Съществуват три типа референции:
- Strong (Силен): Увеличава брояча на референциите на обекта. Това е подразбиращият се тип референция.
- Weak (Слаб): Не увеличава брояча на референциите. Използва се за предотвратяване на цикли на силни референции, когато два обекта се реферират взаимно силно. Слабата референция става
nil, ако обектът, към който отива, бъде освободен. Определя се с ключовата думаweak. - Unowned (Безвластен): Не увеличава брояча на референциите и винаги има стойност. Използва се, когато е известно, че референцията винаги ще сочи към обект, докато той съществува. За разлика от
weak, безвластната референция не ставаnilи може да предизвика срив, ако се опитате да достъпите обекта след неговото освобождаване. Определя се с ключовата думаunowned.
Пример за цикъл на силни референции:
class Human {
let name: String
var apartment: Apartment? // Силна референция към опционален Apartment
init(name: String) {
self.name = name
print("\(name) се инициализира")
}
deinit {
print("\(name) се деинициализира")
}
}
class Apartment {
let unit: String
var tenant: Human? // Силна референция към опционален Human
init(unit: String) {
self.unit = unit
print("Апартамент \(unit) се инициализира")
}
deinit {
print("Апартамент \(unit) се деинициализира")
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Нито "John Appleseed се деинициализира", нито "Apartment 4A се деинициализира" ще бъде изведено поради цикъл на силни референции
Решение на проблема с цикъл на силни референции чрез използване на weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) се инициализира")
}
deinit {
print("\(name) се деинициализира")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Слаба референция
init(unit: String) {
self.unit = unit
print("Апартамент \(unit) се инициализира")
}
deinit {
print("Апартамент \(unit) се деинициализира")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John се освобождава, защото неговият брояч на референциите става 0
unit4A = nil // Апартаментът се освобождава, защото неговият брояч на референциите става 0