Каква е разликата между Wick връзки и Anound връзки?
sobes.tech AI
Отговор от AI
Wick-ссылка (weak) — това е невладееща препратка. Тя не увеличава броя на препратките към обекта. Използва се за предотвратяване на цикли на силни препратки, например между делегат и неговия собственик. Ако обектът, към който сочи слабата препратка, бъде деалокиран, слабата препратка автоматично става nil.
Unowned-ссылка (unowned) — също е невладееща препратка и не увеличава броя на препратките към обекта. Разликата от weak е, че unowned не може да бъде опционална (Optional) и винаги трябва да сочи към съществуващ обект. Ако обектът, към който сочи unowned препратката, бъде деалокиран преди препратката да престане да съществува, опитът за достъп до тази препратка ще доведе до грешка при изпълнение (фатална грешка). Използва се там, където жизненият цикъл на свързания обект е гарантирано по-дълъг или равен на жизнения цикъл на обекта с unowned-препратка (например, цикъл на силни препратки, където един от обектите има ясно определен жизнен цикъл).
Сравнение:
| Характеристика | weak |
unowned |
|---|---|---|
| Невладееща | Да | Да |
| Увеличава SC | Не | Не |
Може да бъде nil |
Да (автоматично нулирано) | Не (трябва да сочи към обект) |
| Безопасност | По-безопасна при възможно деалокиране | По-малко безопасна (фатална грешка при достъп до деалокирания) |
| Тип | Трябва да бъде опционална | Не може да бъде опционална (по подразбиране) |
| Използване | Предотвратяване на цикли на силни препратки, където обектът може да престане да съществува по-рано | Предотвратяване на цикли на силни препратки, където обектът е гарантирано съществуващ |
Пример за използване на weak за предотвратяване на цикъл на силни препратки:
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
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Apartment \(unit) е инициализиран")
}
deinit {
print("Apartment \(unit) е деинициализиран")
}
}
Пример за използване на unowned в контекста на захващане на self в затваряне:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // unowned self за избягване на цикъл на задържане с затваряне
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) е деинициализиран")
}
}