Ответ
Для классов:
В extension класса можно добавлять только convenience-инициализаторы:
class Person {
let name: String
let age: Int
// Designated инициализатор - только в основном объявлении
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
// Convenience инициализатор - можно в extension
convenience init(name: String) {
self.init(name: name, age: 0)
}
// Еще один convenience инициализатор
convenience init() {
self.init(name: "Unknown", age: 0)
}
}
Для структур и перечислений:
Можно добавлять любые инициализаторы, так как у них нет наследования:
struct Point {
var x: Double
var y: Double
}
extension Point {
// Можно добавить designated инициализатор для структуры
init(value: Double) {
self.x = value
self.y = value
}
}
enum CompassDirection {
case north, south, east, west
}
extension CompassDirection {
// Инициализатор для enum
init(from string: String) {
switch string.lowercased() {
case "n": self = .north
case "s": self = .south
// ...
default: self = .north
}
}
}
Ограничения для extension классов:
- Нельзя добавлять designated инициализаторы
- Нельзя добавлять required инициализаторы
- Нельзя добавлять deinitializer
- Нельзя добавлять инициализаторы, если класс помечен как
@frozen
Практический пример с UIKit:
extension UIViewController {
// Convenience инициализатор для UIViewController
convenience init(nibName: String? = nil) {
self.init(nibName: nibName, bundle: nil)
}
}
Рекомендации:
- Используйте extension для добавления convenience инициализаторов, которые предоставляют значения по умолчанию
- Добавляйте инициализаторы в extension для лучшей организации кода
- Помните, что required инициализаторы должны быть в основном объявлении класса