В чем заключается отличие между Wick-ссылками и Anound-ссылками?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Wick-ссылка (weak) — это невладеющая ссылка. Она не увеличивает счетчик ссылок объекта. Используется для предотвращения циклов сильных ссылок, например, между делегатом и его владельцем. Если объект, на который указывает слабая ссылка, деаллоцируется, слабая ссылка автоматически становится nil.
Unowned-ссылка (unowned) — это также невладеющая ссылка и не увеличивает счетчик ссылок объекта. Отличие от weak в том, что unowned не может быть опционалом (Optional) и всегда должна указывать на существующий объект. Если объект, на который указывает unowned ссылка, деаллоцируется до того, как ссылка перестанет существовать, попытка доступа к этой ссылке приведет к ошибке выполнения (fatal error). Используется там, где жизненный цикл связанного объекта гарантированно дольше или равен жизненному циклу объекта с unowned-ссылкой (например, цикл сильных ссылок, где один из объектов имеет четко определенный жизненный цикл).
Сравнение:
| Особенность | weak |
unowned |
|---|---|---|
| Невладеющая | Да | Да |
| Увеличивает SC | Нет | Нет |
| Может быть nil | Да (автоматически обнуляется) | Нет (должна указывать на объект) |
| Безопасность | Более безопасна при возможном деаллоцировании | Менее безопасна (фатальная ошибка при доступе к деаллоцированному) |
| Тип | Должна быть optional | Не может быть optional (по умолчанию) |
| Использование | Предотвращение циклов сильных ссылок, где объект может перестать существовать раньше | Предотвращение циклов сильных ссылок, где объект гарантированно существует |
Пример использования weak для предотвращения цикла сильных ссылок:
class Person {
let name: String
weak var apartment: Apartment? // weak reference to avoid retain cycle
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Apartment \(unit) is being initialized")
}
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
Пример использования unowned в контексте захвата self в замыкании:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // unowned self to avoid retain cycle with closure
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) is being deinitialized")
}
}