Назад к вопросам
Junior
120
questionbank

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

Sobes Copilot

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

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

sobes.tech AI

В Swift существует три основных типа ссылок:

  1. Strong Reference: Стандартный тип. Увеличивает счетчик ссылок (reference count) объекта. Объект не будет освобожден из памяти, пока на него существует хотя бы одна сильная ссылка.

  2. Weak Reference: Неувеличивающий счетчик ссылок. Помечается ключевым словом weak. Используется для предотвращения циклов сильных ссылок (retain cycles), когда два объекта сильно ссылаются друг на друга. Слабая ссылка является опционалом, так как объект может быть деаллоцирован в любой момент.

    // Пример Weak Reference
    class Person {
        let name: String
        weak var apartment: Apartment? // Слабая ссылка
        init(name: String) { self.name = name }
        deinit { print("\(name) is being deinitialized") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Сильная ссылка
        init(unit: String) { self.unit = unit }
        deinit { print("Apartment \(unit) is being deinitialized") }
    }
    
    var john: Person? = Person(name: "John Appleseed")
    var unit4A: Apartment? = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john
    
     john = nil // John деаллоцируется, так как Apartment.tenant не держит сильной ссылки
    
  3. Unowned Reference: Неувеличивающий счетчик ссылок, помечается ключевым словом unowned. Используется, когда уверен, что ссылка всегда будет указывать на объект с большим или таким же временем жизни. В отличие от weak, неуправляемая ссылка не является опционалом. Попытка доступа к объекту через неуправляемую ссылку после его деаллокации приведет к ошибке выполнения (runtime error).

    // Пример Unowned Reference
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) { self.name = name }
        deinit { print("\(name) is being deinitialized") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Неуправляемая ссылка
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Credit Card #\(number) is being deinitialized") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    john = nil // Оба объекта деаллоцируются
    

Краткое сравнение:

Тип Ссылки Увеличивает Retain Count Optional Runtime Check Использование
Strong Да Нет Нет По умолчанию; где нужен полный контроль жизни
Weak Нет Да Да Предотвращение циклов; объект может исчезнуть
Unowned Нет Нет Нет (попытка доступа к nil вызывает ошибку) Предотвращение циклов; уверен, что объект существует