Что означает модификатор convenience для инициализатора в Swift?

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

Ответ

convenience — модификатор, обозначающий вспомогательный инициализатор класса, который предоставляет альтернативный способ создания экземпляра с упрощёнными параметрами.

Основные правила

  1. Должен вызывать designated инициализатор того же класса через self.init(...)
  2. Не может вызывать super.init (это делает designated инициализатор)
  3. Не может быть переопределён в подклассах
  4. Может вызывать другие convenience инициализаторы, но цепочка должна завершиться designated инициализатором

Пример

class Person {
    let name: String
    let age: Int
    let city: String

    // Designated инициализатор
    init(name: String, age: Int, city: String) {
        self.name = name
        self.age = age
        self.city = city
    }

    // Convenience инициализатор 1
    convenience init(name: String, age: Int) {
        self.init(name: name, age: age, city: "Unknown")
    }

    // Convenience инициализатор 2 (вызывает другой convenience)
    convenience init(name: String) {
        self.init(name: name, age: 0) // Вызывает convenience init(name:age:)
    }
}

// Использование
let person1 = Person(name: "Alice", age: 30, city: "Moscow") // Designated
let person2 = Person(name: "Bob", age: 25) // Convenience (city = "Unknown")
let person3 = Person(name: "Charlie") // Convenience (age = 0, city = "Unknown")

Цепочка инициализации

convenience init(name: String)
           ↓
convenience init(name: String, age: Int)
           ↓
designated init(name: String, age: Int, city: String)

Когда использовать

  • Предоставление значений по умолчанию для некоторых параметров
  • Создание объекта из другого формата данных
  • Упрощение API класса для частых случаев использования

Важно: Convenience инициализаторы не могут устанавливать значения свойствам до вызова designated инициализатора. Все свойства должны быть инициализированы в designated инициализаторе.