Какой вид ссылок гарантирует существование объекта?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Типы ссылок и гарантии существования объекта
ARC (Automatic Reference Counting) в Swift
В Swift существуют разные типы ссылок, которые по-разному влияют на жизненный цикл объекта.
1. Strong Reference (强引用)
Увеличивает счётчик удержания (retain count).
class Person {
var name: String
deinit { print("Person deinitialized") }
}
var person: Person? = Person() // Retain count = 1
print(person?.name) // Object exists
person = nil // Retain count = 0
// Output: "Person deinitialized"
Strong reference гарантирует: Объект существует, пока на него есть strong ссылка.
2. Weak Reference (弱引用)
Не увеличивает счётчик удержания.
class Parent {
var child: Child?
}
class Child {
weak var parent: Parent? // Weak ссылка
}
var parent: Parent? = Parent() // Retain count = 1
var child: Child? = Child() // Retain count = 1
parent?.child = child
child?.parent = parent // Не увеличивает retain count родителя
parent = nil // Retain count родителя = 0
// Parent деаллоцируется, даже если child ещё на него ссылается
print(child?.parent) // nil (because parent was deallocated)
Weak reference НЕ гарантирует: Объект может быть удалён в любой момент.
3. Unowned Reference (无主引用)
Не увеличивает счётчик, но предполагает, что объект всегда существует.
class CreditCard {
var owner: Person? // Strong: владеет
}
class Person {
unowned let card: CreditCard // Unowned: уверены, что card существует
init(card: CreditCard) {
self.card = card
}
}
let person = Person(card: CreditCard())
print(person.card) // Safe, потому что person владеет card
Unowned reference гарантирует: Объект существует, пока существует владелец.
Сравнение типов ссылок
| Тип | Retain Count | Гарантия | Когда использовать |
|---|---|---|---|
| Strong | +1 | Объект существует | Parent → Child |
| Weak | 0 | Может быть nil | Delegate pattern |
| Unowned | 0 | Всегда существует | Closure capture |
Практические примеры
Strong Reference:
class Container {
var items: [String] = []
func addItem(_ item: String) {
items.append(item) // Strong ссылка, items существуют
}
}
let container = Container()
container.addItem("Apple")
// items существуют, пока существует container
Weak Reference (Delegate):
protocol UserDelegate: AnyObject {
func userDidUpdate()
}
class UserManager {
weak var delegate: UserDelegate? // Не владеем delegate
func updateUser() {
delegate?.userDidUpdate() // delegate может быть nil
}
}
Unowned Reference (Closure):
class User {
let name: String
var onUpdate: (() -> Void)?
init(name: String) {
self.name = name
// self существует, пока существует User
onUpdate = { [unowned self] in
print("User \(self.name) updated")
}
}
}
Жизненный цикл объектов
1. Создание
var person = Person()
// Retain count = 1 (person ссылается)
2. Добавляем strong ссылку
var friend = person
// Retain count = 2 (person и friend)
3. Удаляем strong ссылку
friend = nil
// Retain count = 1 (только person)
4. Удаляем последнюю strong ссылку
person = nil
// Retain count = 0
// deinit вызывается, объект удаляется
Когда объект гарантированно существует
✅ Во время выполнения strong ссылки на него ✅ Во время выполнения unowned ссылки (если владелец существует) ✅ В параметре функции (параметр = strong ссылка) ✅ В локальной переменной (пока в scope)
❌ Не гарантировано: weak ссылка ❌ Не гарантировано: после удаления всех strong ссылок
Отладка Retain Count
import Foundation
let person = Person()
print(CFGetRetainCount(person as CFTypeRef) - 1) // -1 для CFTypeRef
Ключевые правила
✅ Strong для ownership (Parent → Child) ✅ Weak для optional relationships (Delegate) ✅ Unowned когда уверены в существовании ✅ [weak self] в closures во всех случаях ✅ [unowned self] только когда уверены ❌ Не смешивай strong в обе стороны (retain cycle)
Понимание типов ссылок критично для управления памятью и избегания утечек в iOS.