Что должен вызвать designated (назначенный) инициализатор в Swift?

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

Ответ

Правило: Designated (назначенный) инициализатор обязан вызвать designated инициализатор своего непосредственного суперкласса.

Пример иерархии:

class Vehicle {
    var numberOfWheels: Int
    // Designated инициализатор базового класса
    init(wheels: Int) {
        self.numberOfWheels = wheels
    }
}

class Bicycle: Vehicle {
    var hasBell: Bool
    // Designated инициализатор подкласса
    init(hasBell: Bool) {
        // 1. Сначала инициализируем ВСЕ свойства своего класса
        self.hasBell = hasBell
        // 2. Затем вызываем designated инициализатор суперкласса
        super.init(wheels: 2) // Обязательный вызов
    }
}

// Convenience инициализатор в конечном счете вызывает designated своего класса
class Car: Vehicle {
    var brand: String

    init(brand: String, wheels: Int) { // Designated
        self.brand = brand
        super.init(wheels: wheels)
    }

    convenience init(brand: String) { // Convenience
        // Должен в итоге вызвать designated своего класса
        self.init(brand: brand, wheels: 4)
    }
}

Ключевые моменты:

  1. Порядок: Сначала инициализируются все свойства текущего класса, только потом — вызов super.init(...).
  2. Нарушение правила приводит к ошибке компиляции.
  3. Convenience инициализаторы вызывают другие инициализаторы того же класса (в итоге цепочка доходит до designated).