В чем отличие между слабыми и сильными ссылками в iOS?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Сильные ссылки увеличивают счетчик ссылок объекта, предотвращая его деаллокацию. Слабые ссылки не увеличивают счетчик ссылок и используются для предотвращения циклов сильных ссылок.
Основное различие:
- Сильная (strong): Удерживает объект в памяти, пока есть хотя бы одна сильная ссылка.
- Слабая (weak): Не удерживает объект в памяти. Если последний сильный владелец освобождает объект, слабая ссылка автоматически становится
nil.
Пример цикла сильных ссылок:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let number: Int
var tenant: Person?
init(number: Int) {
self.number = number
print("Apartment \(number) is being initialized")
}
deinit {
print("Apartment \(number) is being deinitialized")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(number: 407)
john!.apartment = unit4A // Strong reference from john to apartment
unit4A!.tenant = john // Strong reference from apartment to john
john = nil // Neither object deinitializes because of the cycle
unit4A = nil
Чтобы решить проблему цикла сильных ссылок, используем слабую ссылку:
class Person {
let name: String
// Weak reference to break the retain cycle
weak var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let number: Int
// Strong reference from apartment to tenant
var tenant: Person?
init(number: Int) {
self.number = number
print("Apartment \(number) is being initialized")
}
deinit {
print("Apartment \(number) is being deinitialized")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(number: 407)
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John is deinitialized
unit4A = nil // Apartment is deinitialized
Используют сильные ссылки по умолчанию. Слабые ссылки используются, когда нет уверенности в жизненном цикле связанного объекта или для предотвращения циклов.
Также существует ссылка unowned, которая похожа на слабую, но предполагает, что связанный объект всегда будет существовать, пока существует ссылка. Если объект освобождается, попытка доступа к unowned ссылке приведет к ошибке времени выполнения. Слабая ссылка в этом случае станет nil. unowned используется, когда два объекта всегда имеют одинаковый жизненный цикл, а один из них всегда будет существовать, пока есть ссылка на другой.
Сводная таблица:
| Тип ссылки | Увеличивает счетчик ссылок | Может стать nil |
Предполагает существование объекта | Применение |
|---|---|---|---|---|
| Strong | Да | Нет | Да | Владение объектом |
| Weak | Нет | Да | Нет (может стать nil) |
Предотвращение циклов сильных ссылок, опциональные связи |
| Unowned | Нет | Нет | Да (программа упадет, если объект освобожден) | Когда объект ссылки имеет такой же или более длительный жизненный цикл |