В чем разница между анонс-ссылкой и вик-ссылкой?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Анонс-ссылка (unowned reference) не увеличивает счетчик ссылок на объект и используется, когда жизненные циклы двух объектов тесно связаны, и один не может существовать без другого, но при этом нет циклической зависимости. Анонс-ссылка гарантированно указывает на существующий объект, поэтому она всегда неопциональна.
Вик-ссылка (weak reference) также не увеличивает счетчик ссылок на объект. Она используется, когда ссылка может в какой-то момент стать нулевой, так как объект, на который она ссылается, может быть освобожден. Вик-ссылка всегда опциональна (weak var).
Пример:
class Person {
let name: String
// strong reference to Apartment
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unitName: String
// weak reference to Person to avoid retain cycle
weak var tenant: Person?
init(unitName: String) {
self.unitName = unitName
print("Apartment \(unitName) is being initialized")
}
deinit {
print("Apartment \(unitName) is being deinitialized")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unitName: "4A")
john!.apartment = unit4A
unit4A!.tenant = john // weak reference here
john = nil // Person object is deallocated
unit4A = nil // Apartment object is deallocated
В данном случае weak var tenant: Person? предотвращает retain cycle между Person и Apartment.
Пример анонс-ссылки:
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class CreditCard {
let number: UInt64
// unowned reference to Customer - a CreditCard must always have a Customer
unowned let customer: Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
print("Card #\(number) is being initialized")
}
deinit {
print("Card #\(number) is being deinitialized")
}
}
var john: Customer? = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // unowned reference here
john = nil // Both Customer and CreditCard are deallocated
В этом примере unowned let customer: Customer используется, так как кредитная карта не может существовать без владельца (Customer), и гарантировано, что customer будет действительным, пока существует CreditCard.