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

Какие существуют виды ссылок в Swift?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech 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 tenent: 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!.tenent = john // Здесь бы возник цикл сильных ссылок без weak
    
    // Ссылки обнуляются, объекты деаллоцируются
    john = nil
    unit4A = nil
    
  3. Unowned Reference (Несобственная ссылка):

    • Не увеличивает счетчик ссылок.
    • Разрешает деаллокацию объекта, если на него больше нет сильных ссылок.
    • Объявляется с использованием ключевого слова unowned.
    • Не является опционалом. Предполагается, что ссылаемый объект всегда будет существовать, пока существует экземпляр, содержащий несобственную ссылку.
    • Использование несобственной ссылки на объект, который уже был деаллоцирован, приведет к ошибке времени выполнения (крашу).
    • Используется для предотвращения циклов сильных ссылок, когда один экземпляр всегда должен существовать, пока существует другой, и нет возможности, чтобы один из них стал nil независимо друг от друга (например, привязка self в замыканиях).
    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).