Из docs
Проверка безопасности 1
Назначенный инициализатор должен гарантировать, что все свойства, введенные его классом, будут инициализированы до он делегирует до инициализатора суперкласса.
blockquote>Зачем нам нужна проверка безопасности, как это?
Чтобы ответить, это позволяет перейти хотя процесс инициализации в быстрый .
Двухфазная инициализация
Инициализация класса в Swift является двухфазным процессом. На первом этапе каждому сохраненному свойству присваивается начальное значение классом, который его представил. Как только начальное состояние для каждого сохраненного свойства определено, начинается вторая фаза, и каждому классу предоставляется возможность настраивать свои сохраненные свойства еще до того, как новый экземпляр считается готовым к использованию.
Использование двухэтапный процесс инициализации делает инициализацию безопасной, но при этом дает полную гибкость каждому классу в иерархии классов. Двухфазная инициализация запрещает доступ к значениям свойств до их инициализации и не позволяет неожиданно устанавливать значения свойств на другое значение другим инициализатором.
blockquote>Итак, чтобы убедиться, что два шага процесс инициализации выполняется, как определено выше, существует четыре проверки безопасности, один из которых:
Проверка безопасности 1
Назначенный инициализатор должен гарантировать, что все введенные свойства по его классу инициализируются до того, как он делегирует до инициализатора суперкласса.
blockquote>Теперь двухфазная инициализация никогда не говорит о порядке, но эта проверка безопасности вводит
super.init
для заказа после инициализация всех свойств.
Проверка безопасности 1 может показаться неуместной, поскольку Двухфазная инициализация запрещает доступ к значениям свойств до их инициализации , без этой безопасности проверьте 1.
Как в этом примере
class Shape { var name: String var sides : Int init(sides:Int, named: String) { self.sides = sides self.name = named } } class Triangle: Shape { var hypotenuse: Int init(hypotenuse:Int) { super.init(sides: 3, named: "Triangle") self.hypotenuse = hypotenuse } }
Triangle.init
инициализируется, каждое свойство перед использованием. Поэтому проверка безопасности 1 кажется несущественной,Но тогда может быть другой сценарий, немного сложный,
class Shape { var name: String var sides : Int init(sides:Int, named: String) { self.sides = sides self.name = named printShapeDescription() } func printShapeDescription() { print("Shape Name :\(self.name)") print("Sides :\(self.sides)") } } class Triangle: Shape { var hypotenuse: Int init(hypotenuse:Int) { self.hypotenuse = hypotenuse super.init(sides: 3, named: "Triangle") } override func printShapeDescription() { super.printShapeDescription() print("Hypotenuse :\(self.hypotenuse)") } } let triangle = Triangle(hypotenuse: 12)
Выход:
Shape Name :Triangle Sides :3 Hypotenuse :12
Здесь если бы мы назовет
super.init
перед установкойhypotenuse
, то вызовsuper.init
затем вызвал быprintShapeDescription()
, и поскольку он был переопределен, он сначала вернется к реализации класса треугольникаprintShapeDescription()
.printShapeDescription()
класса Triangle получает доступ кhypotenuse
не факультативному свойству, которое еще не было инициализировано. И это недопустимо как . Двухфазная инициализация запрещает доступ к значениям свойств до их инициализации. Поэтому убедитесь, что двухфазная инициализация выполнена, как определено, необходимо, чтобы конкретный порядок вызова
super.init
, то есть после инициализации всех свойств, введенных классомself
, нам нужна проверка безопасности 1