В чем разница между weak и unowned в Swift и когда использовать unowned?

«В чем разница между weak и unowned в Swift и когда использовать unowned?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

unowned — это модификатор ссылки в Swift, который, как и weak, не увеличивает счетчик ссылок (retain count), но, в отличие от weak, не является опциональным. Это означает, что unowned ссылка всегда должна указывать на существующий объект.

Ключевые отличия от weak:

  • weak ссылки автоматически становятся nil при освобождении объекта.
  • unowned ссылки при освобождении объекта становятся "висячими" (dangling). Попытка доступа к ним вызывает краш приложения.

Когда использовать unowned: Используйте unowned, когда время жизни ссылающегося объекта гарантированно короче или равно времени жизни объекта, на который ссылаются. Типичный случай — устранение цикла сильных ссылок в отношениях «родитель-ребенок», где родитель владеет ребенком.

Пример:

class Parent {
    var child: Child?
}

class Child {
    // Ребенок не должен переживать родителя, поэтому unowned безопасен.
    unowned let parent: Parent

    init(parent: Parent) {
        self.parent = parent
    }
}

⚠️ Важные правила:

  1. Используйте unowned, только если абсолютно уверены, что объект не будет освобожден раньше ссылки.
  2. В асинхронных сценариях (например, внутри замыканий, которые могут пережить захваченный объект) почти всегда безопаснее использовать weak.
  3. unowned может дать небольшой прирост производительности, так как не требует проверки на nil, но риски обычно перевешивают выгоду.