Назад к вопросам
Middle
79
questionbank

В чем разница между анонс-ссылкой и вик-ссылкой?

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.