Sobes.tech
Middle

Дар Swift кадом намудҳои истинод вуҷуд доранд?

sobes.tech AI

Ҷавоб аз AI

В Swift съществуват три основни вида референции:

  1. Strong Reference (Здрава референция):

    • Увеличава брояча на референциите към обекта.
    • Предотвратява освобождаването на обекта, докато има поне една здрава референция към него.
    • Това е подразбиращият се тип референция в Swift.
    • Може да доведе до циклични референции.
  2. Weak Reference (Слаба референция):

    • Не увеличава брояча на референциите.
    • Позволява освобождаването на обекта, ако на него вече няма здрави референции.
    • Обявява се с ключовата дума weak.
    • Винаги е опционална (Optional), тъй като реферираният обект може да бъде nil.
    • Използва се за предотвратяване на циклични референции.
    class Person {
        let name: String
        weak var apartment: Apartment? // Слаба референция
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) е освободен") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Обикновена здрава референция
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Апартамент \(unit) е освободен") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Тук би възникнала циклична референция без `weak`
    
    // Референциите се нулират, обектите се освобождават
    john = nil
    unit4A = nil
    
  3. Unowned Reference (Несобствена референция):

    • Не увеличава брояча на референциите.
    • Позволява освобождаването на обекта, ако на него вече няма здрави референции.
    • Обявява се с ключовата дума unowned.
    • Не е опционална. Предполага се, че реферираният обект винаги ще съществува, докато съществува съдържащият го екземпляр.
    • Достъпът до освободения обект чрез unowned ще доведе до грешка в изпълнението (crash).
    • Използва се за предотвратяване на циклични референции, когато един обект винаги трябва да съществува, докато съществува другият, и не може да стане nil независимо един от друг.
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) е освободен") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Несобствена референция
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Кредитна карта #\(number) е освободена") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Ако изтрием клиента, картата, която реферира към него с `unowned`, ще стане невалидна, но няма да създаде цикъл.
    john = nil // Обе обекта се освобождават
    

Изборът между weak и unowned зависи от характера на връзката между обектите: използвайте weak, когато един обект може да съществува без другия (Person без Apartment), и unowned, когато един обект винаги трябва да съществува, докато съществува другият (CreditCard винаги принадлежи на Customer).