Какой жизненный цикл у reference type (класса) в Swift?

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

Ответ

Жизненный цикл экземпляра класса (reference type) в Swift управляется Automatic Reference Counting (ARC) и состоит из трёх фаз:

  1. Выделение и инициализация

    • Память выделяется под объект.
    • Вызывается назначенный инициализатор (init), который устанавливает начальные значения свойств.
      class User {
      let name: String
      init(name: String) {
          self.name = name
          print("User (name) инициализирован")
      }
      }
  2. Использование

    • Объект находится в памяти, пока существует хотя бы одна сильная (strong) ссылка на него.
    • ARC автоматически увеличивает и уменьшает счётчик ссылок.
  3. Освобождение памяти

    • Когда счётчик сильных ссылок достигает нуля, объект помечается к удалению.
    • Вызывается деинициализатор (deinit) для освобождения ресурсов (закрытие файлов, отмена сетевых запросов).
    • Память возвращается системе.
      
      class User {
      deinit {
          print("User (name) деинициализирован")
      }
      }

    do { let user = User(name: "Alice") // User Alice инициализирован } // При выходе из области видимости user деинициализирован

Критически важное понятие — циклы сильных ссылок:

class Person {
    var apartment: Apartment?
}
class Apartment {
    var tenant: Person? // Сильная ссылка → Цикл!
}

var john: Person? = Person()
var unit4A: Apartment? = Apartment()
john?.apartment = unit4A
unit4A?.tenant = john // Цикл сильных ссылок!

john = nil
unit4A = nil // Память НЕ освобождается! Утечка.

Решение: использовать weak (ссылка становится nil при освобождении объекта) или unowned (предполагает, что объект существует) ссылки для разрыва циклов.