Классы, структуры и перечисления, однажды объявленные в Swift 4, инициализируются для подготовки экземпляра класса. Начальное значение инициализируется для сохраненного свойства, а также для новых экземпляров. Инициализируются значения, чтобы продолжить работу. Ключевое слово для создания функции инициализации выполняется методом init (). Инициализатор Swift 4 отличается от Objective-C тем, что он не возвращает никаких значений. Его функция заключается в проверке инициализации вновь созданных экземпляров перед их обработкой. Swift 4 также предоставляет процесс «деинициализации» для выполнения операций управления памятью после освобождения экземпляров.
Роль инициализатора для сохраненных свойств
Сохраненное свойство должно инициализировать экземпляры для своих классов и структур перед обработкой экземпляров. Хранимые свойства используют инициализатор для назначения и инициализации значений, тем самым устраняя необходимость вызова наблюдателей свойств. Инициализатор используется в хранимом свойстве
-
Создать начальное значение.
-
Чтобы назначить значение свойства по умолчанию в определении свойства.
-
Для инициализации экземпляра для определенного типа данных используется init (). Внутри функции init () аргументы не передаются.
Создать начальное значение.
Чтобы назначить значение свойства по умолчанию в определении свойства.
Для инициализации экземпляра для определенного типа данных используется init (). Внутри функции init () аргументы не передаются.
Синтаксис
init() { //New Instance initialization goes here }
пример
struct rectangle { var length: Double var breadth: Double init() { length = 6 breadth = 12 } } var area = rectangle() print("area of rectangle is \(area.length*area.breadth)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
area of rectangle is 72.0
Здесь структура ‘rectangle’ инициализируется с длиной и шириной элементов как ‘Double’ типы данных. Метод Init () используется для инициализации значений для вновь создаваемых элементов длины и двойника. Площадь прямоугольника вычисляется и возвращается путем вызова функции прямоугольника.
Установка значений свойств по умолчанию
Язык Swift 4 предоставляет функцию Init () для инициализации значений сохраненных свойств. Кроме того, пользователь может инициализировать значения свойств по умолчанию при объявлении членов класса или структуры. Когда свойство принимает одно и то же значение во всей программе, мы можем объявить его только в разделе объявления, а не инициализировать его в init (). Установка значений свойств по умолчанию позволяет пользователю, когда наследование определено для классов или структур.
struct rectangle { var length = 6 var breadth = 12 } var area = rectangle() print("area of rectangle is \(area.length*area.breadth)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
area of rectangle is 72
Здесь вместо объявления длины и ширины в init () значения инициализируются в самом объявлении.
Инициализация параметров
В языке Swift 4 пользователь имеет возможность инициализировать параметры как часть определения инициализатора с помощью init ().
struct Rectangle { var length: Double var breadth: Double var area: Double init(fromLength length: Double, fromBreadth breadth: Double) { self.length = length self.breadth = breadth area = length * breadth } init(fromLeng leng: Double, fromBread bread: Double) { self.length = leng self.breadth = bread area = leng * bread } } let ar = Rectangle(fromLength: 6, fromBreadth: 12) print("area is: \(ar.area)") let are = Rectangle(fromLeng: 36, fromBread: 12) print("area is: \(are.area)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
area is: 72.0 area is: 432.0
Локальные и внешние параметры
Параметры инициализации имеют как локальные, так и глобальные имена параметров, аналогичные параметрам функций и методов. Объявление локального параметра используется для доступа в теле инициализации, а объявление внешнего параметра используется для вызова инициализатора. Инициализаторы Swift 4 отличаются от инициализатора функций и методов тем, что не определяют, какой инициализатор используется для вызова каких функций.
Чтобы преодолеть это, Swift 4 вводит автоматическое внешнее имя для каждого параметра в init (). Это автоматическое внешнее имя эквивалентно локальному имени, записанному перед каждым параметром инициализации.
struct Days { let sunday, monday, tuesday: Int init(sunday: Int, monday: Int, tuesday: Int) { self.sunday = sunday self.monday = monday self.tuesday = tuesday } init(daysofaweek: Int) { sunday = daysofaweek monday = daysofaweek tuesday = daysofaweek } } let week = Days(sunday: 1, monday: 2, tuesday: 3) print("Days of a Week is: \(week.sunday)") print("Days of a Week is: \(week.monday)") print("Days of a Week is: \(week.tuesday)") let weekdays = Days(daysofaweek: 4) print("Days of a Week is: \(weekdays.sunday)") print("Days of a Week is: \(weekdays.monday)") print("Days of a Week is: \(weekdays.tuesday)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Days of a Week is: 1 Days of a Week is: 2 Days of a Week is: 3 Days of a Week is: 4 Days of a Week is: 4 Days of a Week is: 4
Параметры без внешних имен
Когда внешнее имя не требуется для инициализации, подчеркивание ‘_’ используется для переопределения поведения по умолчанию.
struct Rectangle { var length: Double init(frombreadth breadth: Double) { length = breadth * 10 } init(frombre bre: Double) { length = bre * 30 } init(_ area: Double) { length = area } } let rectarea = Rectangle(180.0) print("area is: \(rectarea.length)") let rearea = Rectangle(370.0) print("area is: \(rearea.length)") let recarea = Rectangle(110.0) print("area is: \(recarea.length)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
area is: 180.0 area is: 370.0 area is: 110.0
Необязательные типы недвижимости
Когда хранимое свойство в каком-то экземпляре не возвращает никакого значения, это свойство объявляется с необязательным типом, указывающим, что для этого конкретного типа не возвращается «никакого значения». Когда сохраненное свойство объявляется как «необязательное», оно автоматически инициализирует значение «nil» во время самой инициализации.
struct Rectangle { var length: Double? init(frombreadth breadth: Double) { length = breadth * 10 } init(frombre bre: Double) { length = bre * 30 } init(_ area: Double) { length = area } } let rectarea = Rectangle(180.0) print("area is: \(rectarea.length)") let rearea = Rectangle(370.0) print("area is: \(rearea.length)") let recarea = Rectangle(110.0) print("area is: \(recarea.length)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
area is: Optional(180.0) area is: Optional(370.0) area is: Optional(110.0)
Изменение свойств константы во время инициализации
Инициализация также позволяет пользователю изменять значение постоянного свойства. Во время инициализации свойство класса позволяет его экземплярам класса изменяться суперклассом, а не подклассом. Рассмотрим, к примеру, в предыдущей программе «длина» объявлена как «переменная» в основном классе. Приведенная ниже программная переменная «length» модифицируется как «постоянная» переменная.
struct Rectangle { let length: Double? init(frombreadth breadth: Double) { length = breadth * 10 } init(frombre bre: Double) { length = bre * 30 } init(_ area: Double) { length = area } } let rectarea = Rectangle(180.0) print("area is: \(rectarea.length)") let rearea = Rectangle(370.0) print("area is: \(rearea.length)") let recarea = Rectangle(110.0) print("area is: \(recarea.length)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
area is: Optional(180.0) area is: Optional(370.0) area is: Optional(110.0)
Инициализаторы по умолчанию
Инициализаторы по умолчанию предоставляют новый экземпляр всем его объявленным свойствам базового класса или структуры со значениями по умолчанию.
class defaultexample { var studname: String? var stmark = 98 var pass = true } var result = defaultexample() print("result is: \(result.studname)") print("result is: \(result.stmark)") print("result is: \(result.pass)")
Когда мы запускаем вышеуказанную программу, используя игровую площадку, мы получаем следующий результат. —
result is: nil result is: 98 result is: true
Вышеуказанная программа определена с именем класса как «defaultexample». Три функции-члена по умолчанию инициализируются как ‘studname?’ хранить значения ‘nil’, ‘stmark’ как 98 и ‘pass’ как логическое значение ‘true’. Аналогично значения членов в классе могут быть инициализированы как значения по умолчанию перед обработкой типов членов класса.
Поэлементные инициализаторы для типов структуры
Когда пользовательские инициализаторы не предоставлены пользователем, типы структуры в Swift 4 автоматически получат «членский инициализатор». Его основная функция заключается в инициализации новых экземпляров структуры по умолчанию для каждого элемента, а затем свойства нового экземпляра передаются элементному элементу инициализации по имени.
struct Rectangle { var length = 100.0, breadth = 200.0 } let area = Rectangle(length: 24.0, breadth: 32.0) print("Area of rectangle is: \(area.length)") print("Area of rectangle is: \(area.breadth)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Area of rectangle is: 24.0 Area of rectangle is: 32.0
Структуры инициализируются по умолчанию для их функций членства во время инициализации для «length» как «100.0» и «width» как «200.0». Но значения переопределяются при обработке переменных длины и ширины как 24.0 и 32.0.
Делегирование инициализатора для типов значений
Делегирование инициализатора определяется как вызов инициализаторов из других инициализаторов. Его основная функция заключается в возможности повторного использования, чтобы избежать дублирования кода между несколькими инициализаторами.
struct Stmark { var mark1 = 0.0, mark2 = 0.0 } struct stdb { var m1 = 0.0, m2 = 0.0 } struct block { var average = stdb() var result = Stmark() init() {} init(average: stdb, result: Stmark) { self.average = average self.result = result } init(avg: stdb, result: Stmark) { let tot = avg.m1 - (result.mark1 / 2) let tot1 = avg.m2 - (result.mark2 / 2) self.init(average: stdb(m1: tot, m2: tot1), result: result) } } let set1 = block() print("student result is: \(set1.average.m1, set1.average.m2) \(set1.result.mark1, set1.result.mark2)") let set2 = block(average: stdb(m1: 2.0, m2: 2.0), result: Stmark(mark1: 5.0, mark2: 5.0)) print("student result is: \(set2.average.m1, set2.average.m2) \(set2.result.mark1, set2.result.mark2)") let set3 = block(avg: stdb(m1: 4.0, m2: 4.0), result: Stmark(mark1: 3.0, mark2: 3.0)) print("student result is: \(set3.average.m1, set3.average.m2) \(set3.result.mark1, set3.result.mark2)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
(0.0,0.0) (0.0,0.0) (2.0,2.0) 5.0,5.0) (2.5,2.5) (3.0,3.0)
Правила для делегирования инициализатора
Типы значений | Типы классов |
---|---|
Наследование не поддерживается для типов значений, таких как структуры и перечисления. Ссылка на другие инициализаторы осуществляется через self.init | Наследование поддерживается. Проверяет, что все сохраненные значения свойств инициализированы |
Наследование и инициализация класса
Типы классов имеют два вида инициализаторов, чтобы проверить, получают ли определенные сохраненные свойства начальное значение, а именно назначенные инициализаторы и удобные инициализаторы.
Назначенные инициализаторы и удобные инициализаторы
Назначенный инициализатор | Удобный инициализатор |
---|---|
Считается первичной инициализацией для класса | Рассматривается как поддерживающая инициализация для класса |
Все свойства класса инициализируются, и для дальнейшей инициализации вызывается соответствующий инициализатор суперкласса. | Назначенный инициализатор вызывается с удобным инициализатором для создания экземпляра класса для конкретного варианта использования или типа входного значения |
По крайней мере один назначенный инициализатор определен для каждого класса | Нет необходимости в обязательном определении удобных инициализаторов, когда класс не требует инициализаторов. |
Init (параметры) {заявления} | удобство init (параметры) {заявления} |
Программа для назначенных инициализаторов
class mainClass { var no1 : Int // local storage init(no1 : Int) { self.no1 = no1 // initialization } } class subClass : mainClass { var no2 : Int // new subclass storage init(no1 : Int, no2 : Int) { self.no2 = no2 // initialization super.init(no1:no1) // redirect to superclass } } let res = mainClass(no1: 10) let print = subClass(no1: 10, no2: 20) print("res is: \(res.no1)") print("res is: \(print.no1)") print("res is: \(print.no2)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
res is: 10 res is: 10 res is: 20
Программа для удобных инициализаторов
class mainClass { var no1 : Int // local storage init(no1 : Int) { self.no1 = no1 // initialization } } class subClass : mainClass { var no2 : Int init(no1 : Int, no2 : Int) { self.no2 = no2 super.init(no1:no1) } // Requires only one parameter for convenient method override convenience init(no1: Int) { self.init(no1:no1, no2:0) } } let res = mainClass(no1: 20) let print = subClass(no1: 30, no2: 50) print("res is: \(res.no1)") print("res is: \(print.no1)") print("res is: \(print.no2)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
res is: 20 res is: 30 res is: 50
Инициализация наследования и переопределение
Swift 4 не позволяет своим подклассам наследовать инициализаторы суперкласса для их типов членов по умолчанию. Наследование применимо к инициализаторам суперкласса только в некоторой степени, что будет обсуждаться в разделе «Автоматическое наследование инициализатора».
Когда пользователю необходимо определить инициализаторы в суперклассе, подкласс с инициализаторами должен быть определен пользователем как пользовательская реализация. Когда переопределение должно выполняться подклассом, необходимо объявить ключевое слово «переопределение» суперкласса.
class sides { var corners = 4 var description: String { return "\(corners) sides" } } let rectangle = sides() print("Rectangle: \(rectangle.description)") class pentagon: sides { override init() { super.init() corners = 5 } } let bicycle = pentagon() print("Pentagon: \(bicycle.description)")
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Rectangle: 4 sides Pentagon: 5 sides
Назначенные и удобные инициализаторы в действии
class Planet { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[No Planets]") } } let plName = Planet(name: "Mercury") print("Planet name is: \(plName.name)") let noplName = Planet() print("No Planets like that: \(noplName.name)") class planets: Planet { var count: Int init(name: String, count: Int) { self.count = count super.init(name: name) } override convenience init(name: String) { self.init(name: name, count: 1) } }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Planet name is: Mercury No Planets like that: [No Planets]
Сбой инициализатора
Пользователь должен получать уведомления о любых ошибках инициализатора при определении значений класса, структуры или перечисления. Инициализация переменных иногда становится неудачной из-за
- Неверные значения параметров.
- Отсутствие необходимого внешнего источника.
- Условие, предотвращающее успешную инициализацию.
Для отлова исключений, генерируемых методом инициализации, Swift 4 производит гибкую инициализацию, называемую «сбойный инициализатор», чтобы уведомить пользователя о том, что что-то осталось незамеченным при инициализации структуры, класса или членов перечисления. Ключевое слово, чтобы поймать сбой инициализатора — «init?». Кроме того, инициализируемые и неисправные инициализаторы не могут быть определены с одинаковыми типами параметров и именами.
struct studrecord { let stname: String init?(stname: String) { if stname.isEmpty {return nil } self.stname = stname } } let stmark = studrecord(stname: "Swing") if let name = stmark { print("Student name is specified") } let blankname = studrecord(stname: "") if blankname == nil { print("Student name is left blank") }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Student name is specified Student name is left blank
Сбойные инициализаторы для перечислений
Язык Swift 4 обеспечивает гибкость, позволяющую использовать инициализаторы Failable для перечислений, чтобы уведомить пользователя, когда члены перечисления не имеют инициализирующих значений.
enum functions { case a, b, c, d init?(funct: String) { switch funct { case "one": self = .a case "two": self = .b case "three": self = .c case "four": self = .d default: return nil } } } let result = functions(funct: "two") if result != nil { print("With In Block Two") } let badresult = functions(funct: "five") if badresult == nil { print("Block Does Not Exist") }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
With In Block Two Block Does Not Exist
Сбойные инициализаторы для классов
Сбойный инициализатор при объявлении с перечислениями и структурами предупреждает об ошибке инициализации при любых обстоятельствах в его реализации. Однако неисправный инициализатор в классах будет предупреждать об ошибке только после того, как для сохраненных свойств будет установлено начальное значение.
class studrecord { let studname: String! init?(studname: String) { self.studname = studname if studname.isEmpty { return nil } } } if let stname = studrecord(studname: "Failable Initializers") { print("Module is \(stname.studname)") }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Module is Optional("Failable Initializers")
Переопределение сбойного инициализатора
Как и в случае инициализации, у пользователя также есть возможность переопределить инициализируемый суперклассом инициализатор внутри подкласса. Отказавшая инициализацию суперкласса также может быть переопределена в нерасширяемом инициализаторе подкласса.
Инициализатор подкласса не может делегировать вплоть до инициализатора суперкласса при переопределении сбойной инициализатора суперкласса с необратимой инициализацией подкласса.
Неисправный инициализатор никогда не может делегировать отказавшему инициализатору.
Приведенная ниже программа описывает сбойные и не сбойные инициализаторы.
class Planet { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[No Planets]") } } let plName = Planet(name: "Mercury") print("Planet name is: \(plName.name)") let noplName = Planet() print("No Planets like that: \(noplName.name)") class planets: Planet { var count: Int init(name: String, count: Int) { self.count = count super.init(name: name) } override convenience init(name: String) { self.init(name: name, count: 1) } }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Planet name is: Mercury No Planets like that: [No Planets]
Посвящение! Сбойный инициализатор
Swift 4 предоставляет ‘init?’ определить необязательный экземпляр неисправного инициализатора. Чтобы определить неявно развернутый необязательный экземпляр определенного типа ‘init!’ указан.
struct studrecord { let stname: String init!(stname: String) { if stname.isEmpty {return nil } self.stname = stname } } let stmark = studrecord(stname: "Swing") if let name = stmark { print("Student name is specified") } let blankname = studrecord(stname: "") if blankname == nil { print("Student name is left blank") }
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —
Student name is specified Student name is left blank
Требуемые инициализаторы
Чтобы объявить каждый подкласс инициализируемого ключевого слова ‘required’, необходимо определить его перед функцией init ().
class classA { required init() { var a = 10 print(a) } } class classB: classA { required init() { var b = 30 print(b) } } let res = classA() let print = classB()
Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —