Учебники

Swift — инициализация

Классы, структуры и перечисления, однажды объявленные в Swift 4, инициализируются для подготовки экземпляра класса. Начальное значение инициализируется для сохраненного свойства, а также для новых экземпляров. Инициализируются значения, чтобы продолжить работу. Ключевое слово для создания функции инициализации выполняется методом init (). Инициализатор Swift 4 отличается от Objective-C тем, что он не возвращает никаких значений. Его функция заключается в проверке инициализации вновь созданных экземпляров перед их обработкой. Swift 4 также предоставляет процесс «деинициализации» для выполнения операций управления памятью после освобождения экземпляров.

Роль инициализатора для сохраненных свойств

Сохраненное свойство должно инициализировать экземпляры для своих классов и структур перед обработкой экземпляров. Хранимые свойства используют инициализатор для назначения и инициализации значений, тем самым устраняя необходимость вызова наблюдателей свойств. Инициализатор используется в хранимом свойстве

  • Создать начальное значение.

  • Чтобы назначить значение свойства по умолчанию в определении свойства.

  • Для инициализации экземпляра для определенного типа данных используется init (). Внутри функции init () аргументы не передаются.

Создать начальное значение.

Чтобы назначить значение свойства по умолчанию в определении свойства.

Для инициализации экземпляра для определенного типа данных используется init (). Внутри функции init () аргументы не передаются.

Синтаксис

init() {
   //New Instance initialization goes here
}

пример

Live Demo

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 (). Установка значений свойств по умолчанию позволяет пользователю, когда наследование определено для классов или структур.

Live Demo

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 ().

Live Demo

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 (). Это автоматическое внешнее имя эквивалентно локальному имени, записанному перед каждым параметром инициализации.

Live Demo

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

Параметры без внешних имен

Когда внешнее имя не требуется для инициализации, подчеркивание ‘_’ используется для переопределения поведения по умолчанию.

Live Demo

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» во время самой инициализации.

Live Demo

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» модифицируется как «постоянная» переменная.

Live Demo

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)

Инициализаторы по умолчанию

Инициализаторы по умолчанию предоставляют новый экземпляр всем его объявленным свойствам базового класса или структуры со значениями по умолчанию.

Live Demo

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 автоматически получат «членский инициализатор». Его основная функция заключается в инициализации новых экземпляров структуры по умолчанию для каждого элемента, а затем свойства нового экземпляра передаются элементному элементу инициализации по имени.

Live Demo

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 не позволяет своим подклассам наследовать инициализаторы суперкласса для их типов членов по умолчанию. Наследование применимо к инициализаторам суперкласса только в некоторой степени, что будет обсуждаться в разделе «Автоматическое наследование инициализатора».

Когда пользователю необходимо определить инициализаторы в суперклассе, подкласс с инициализаторами должен быть определен пользователем как пользовательская реализация. Когда переопределение должно выполняться подклассом, необходимо объявить ключевое слово «переопределение» суперкласса.

Live Demo

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

Назначенные и удобные инициализаторы в действии

Live Demo

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?». Кроме того, инициализируемые и неисправные инициализаторы не могут быть определены с одинаковыми типами параметров и именами.

Live Demo

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 для перечислений, чтобы уведомить пользователя, когда члены перечисления не имеют инициализирующих значений.

Live Demo

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

Сбойные инициализаторы для классов

Сбойный инициализатор при объявлении с перечислениями и структурами предупреждает об ошибке инициализации при любых обстоятельствах в его реализации. Однако неисправный инициализатор в классах будет предупреждать об ошибке только после того, как для сохраненных свойств будет установлено начальное значение.

Live Demo

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")

Переопределение сбойного инициализатора

Как и в случае инициализации, у пользователя также есть возможность переопределить инициализируемый суперклассом инициализатор внутри подкласса. Отказавшая инициализацию суперкласса также может быть переопределена в нерасширяемом инициализаторе подкласса.

Инициализатор подкласса не может делегировать вплоть до инициализатора суперкласса при переопределении сбойной инициализатора суперкласса с необратимой инициализацией подкласса.

Неисправный инициализатор никогда не может делегировать отказавшему инициализатору.

Приведенная ниже программа описывает сбойные и не сбойные инициализаторы.

Live Demo

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!’ указан.

Live Demo

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 ().

Live Demo

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()

Когда мы запускаем вышеуказанную программу, используя площадку, мы получаем следующий результат —