Swift - Initialisierung
Klassen, Strukturen und Aufzählungen, die einmal in Swift 4 deklariert wurden, werden für die Vorbereitung der Instanz einer Klasse initialisiert. Der Anfangswert wird für gespeicherte Eigenschaften initialisiert, und auch für neue Instanzen werden die Werte initialisiert, um fortzufahren. Das Schlüsselwort zum Erstellen der Initialisierungsfunktion wird von der Methode 'init ()' ausgeführt. Der Swift 4-Initialisierer unterscheidet sich von Objective-C darin, dass er keine Werte zurückgibt. Seine Funktion besteht darin, vor der Verarbeitung zu überprüfen, ob neu erstellte Instanzen initialisiert wurden. Swift 4 bietet auch einen Deinitialisierungsprozess zum Ausführen von Speicherverwaltungsvorgängen, sobald die Zuordnung der Instanzen aufgehoben wurde.
Initialisierungsrolle für gespeicherte Eigenschaften
Gespeicherte Eigenschaften müssen die Instanzen für ihre Klassen und Strukturen initialisieren, bevor die Instanzen verarbeitet werden. Gespeicherte Eigenschaften verwenden den Initialisierer, um Werte zuzuweisen und zu initialisieren, wodurch das Aufrufen von Eigenschaftsbeobachtern entfällt. Der Initialisierer wird in gespeicherten Eigenschaften verwendet
So erstellen Sie einen Anfangswert.
So weisen Sie den Standardeigenschaftswert innerhalb der Eigenschaftsdefinition zu
Zum Initialisieren einer Instanz für einen bestimmten Datentyp wird 'init ()' verwendet. Innerhalb der Funktion init () werden keine Argumente übergeben.
Syntax
init() {
//New Instance initialization goes here
}
Beispiel
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
area of rectangle is 72.0
Hier wird die Struktur 'Rechteck' mit der Länge und Breite der Elemente als 'Doppelte' Datentypen initialisiert. Die Methode Init () wird verwendet, um die Werte für die Länge und das Double der neu erstellten Elemente zu initialisieren. Die Fläche des Rechtecks wird berechnet und durch Aufrufen der Rechteckfunktion zurückgegeben.
Standardmäßig Eigenschaftswerte festlegen
Die Sprache Swift 4 bietet die Funktion Init () zum Initialisieren der gespeicherten Eigenschaftswerte. Außerdem kann der Benutzer die Eigenschaftswerte standardmäßig initialisieren, während er die Klassen- oder Strukturelemente deklariert. Wenn die Eigenschaft im gesamten Programm denselben Wert annimmt, können wir ihn allein im Deklarationsabschnitt deklarieren, anstatt ihn in init () zu initialisieren. Durch das standardmäßige Festlegen von Eigenschaftswerten wird der Benutzer aktiviert, wenn die Vererbung für Klassen oder Strukturen definiert ist.
struct rectangle {
var length = 6
var breadth = 12
}
var area = rectangle()
print("area of rectangle is \(area.length*area.breadth)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
area of rectangle is 72
Anstatt in init () Länge und Breite zu deklarieren, werden hier die Werte in der Deklaration selbst initialisiert.
Parameter Initialisierung
In der Sprache Swift 4 kann der Benutzer Parameter als Teil der Definition des Initialisierers mit init () initialisieren.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
area is: 72.0
area is: 432.0
Lokale und externe Parameter
Initialisierungsparameter haben sowohl lokale als auch globale Parameternamen, die denen von Funktions- und Methodenparametern ähnlich sind. Die lokale Parameterdeklaration wird verwendet, um auf den Initialisierungskörper zuzugreifen, und die externe Parameterdeklaration wird verwendet, um den Initialisierer aufzurufen. Swift 4-Initialisierer unterscheiden sich vom Funktions- und Methodeninitialisierer dadurch, dass sie nicht identifizieren, mit welchem Initialisierer welche Funktionen aufgerufen werden.
Um dies zu überwinden, führt Swift 4 für jeden Parameter in init () einen automatischen externen Namen ein. Dieser automatische externe Name entspricht dem lokalen Namen, der vor jedem Initialisierungsparameter geschrieben wurde.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
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
Parameter ohne externe Namen
Wenn für eine Initialisierung kein externer Name benötigt wird, wird der Unterstrich '_' verwendet, um das Standardverhalten zu überschreiben.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
area is: 180.0
area is: 370.0
area is: 110.0
Optionale Eigenschaftstypen
Wenn die gespeicherte Eigenschaft in einer Instanz keinen Wert zurückgibt, wird diese Eigenschaft mit einem 'optionalen' Typ deklariert, der angibt, dass für diesen bestimmten Typ 'kein Wert' zurückgegeben wird. Wenn die gespeicherte Eigenschaft als 'optional' deklariert wird, wird der Wert während der Initialisierung selbst automatisch auf 'nil' initialisiert.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
Ändern der Konstanteneigenschaften während der Initialisierung
Durch die Initialisierung kann der Benutzer auch den Wert der konstanten Eigenschaft ändern. Während der Initialisierung ermöglicht die class-Eigenschaft, dass ihre Klasseninstanzen von der Superklasse und nicht von der Unterklasse geändert werden. Betrachten Sie zum Beispiel im vorherigen Programm, dass 'Länge' in der Hauptklasse als 'Variable' deklariert ist. Die folgende Programmvariable 'Länge' wird als 'Konstante' geändert.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
Standardinitialisierer
Standardinitialisierer stellen eine neue Instanz für alle deklarierten Eigenschaften der Basisklasse oder -struktur mit Standardwerten bereit.
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)")
Wenn wir über dem Programm auf dem Spielplatz laufen, erhalten wir folgendes Ergebnis. - -
result is: nil
result is: 98
result is: true
Das obige Programm wird mit dem Klassennamen 'defaultexample' definiert. Drei Mitgliedsfunktionen werden standardmäßig als 'Studname?' Initialisiert. Um 'Null'-Werte zu speichern,' stmark 'als 98 und' pass 'als Booleschen Wert' true '. Ebenso können die Elementwerte in der Klasse standardmäßig initialisiert werden, bevor die Klassenelementtypen verarbeitet werden.
Mitgliedsweise Initialisierer für Strukturtypen
Wenn die benutzerdefinierten Initialisierer nicht vom Benutzer bereitgestellt werden, erhalten die Strukturtypen in Swift 4 automatisch den 'Mitgliedsinitialisierer'. Die Hauptfunktion besteht darin, die neuen Strukturinstanzen mit der Standardinitialisierung zu initialisieren. Anschließend werden die neuen Instanzeigenschaften nach Namen an die Mitgliedsinitialisierung übergeben.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Area of rectangle is: 24.0
Area of rectangle is: 32.0
Strukturen werden standardmäßig für ihre Zugehörigkeitsfunktionen während der Initialisierung für 'Länge' als '100.0' und 'Breite' als '200.0' initialisiert. Die Werte werden jedoch während der Verarbeitung der Variablen Länge und Breite als 24.0 und 32.0 überschrieben.
Initialisierungsdelegation für Werttypen
Initializer-Delegierung ist definiert als Aufrufen von Initialisierern von anderen Initialisierern. Seine Hauptfunktion besteht darin, als Wiederverwendbarkeit zu fungieren, um Codeduplizierungen über mehrere Initialisierer hinweg zu vermeiden.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)
Regeln für die Initialisierungsdelegation
Werttypen | Klassentypen |
---|---|
Die Vererbung wird für Werttypen wie Strukturen und Aufzählungen nicht unterstützt. Das Verweisen auf andere Initialisierer erfolgt über self.init | Vererbung wird unterstützt. Überprüft, ob alle gespeicherten Eigenschaftswerte initialisiert wurden |
Klassenvererbung und -initialisierung
Klassentypen haben zwei Arten von Initialisierern, um zu überprüfen, ob definierte gespeicherte Eigenschaften einen Anfangswert erhalten, nämlich bestimmte Initialisierer und Komfortinitialisierer.
Designated Initializers und Convenience Initializers
Designated Initializer | Convenience Initializer |
---|---|
Wird als primäre Initialisierung für eine Klasse betrachtet | Wird als unterstützende Initialisierung für eine Klasse angesehen |
Alle Klasseneigenschaften werden initialisiert und der entsprechende Superklasseninitialisierer wird zur weiteren Initialisierung aufgerufen | Der designierte Initialisierer wird mit dem praktischen Initialisierer aufgerufen, um eine Klasseninstanz für einen bestimmten Anwendungsfall oder Eingabewerttyp zu erstellen |
Für jede Klasse ist mindestens ein bestimmter Initialisierer definiert | Convenience-Initialisierer müssen nicht definiert werden, wenn für die Klasse keine Initialisierer erforderlich sind. |
Init (Parameter) {Anweisungen} | Convenience Init (Parameter) {Anweisungen} |
Programm für designierte Initialisierer
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
res is: 10
res is: 10
res is: 20
Programm für Convenience-Initialisierer
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
res is: 20
res is: 30
res is: 50
Vererbung und Überschreiben des Initialisierers
Swift 4 erlaubt seinen Unterklassen standardmäßig nicht, seine Superklasseninitialisierer für ihre Elementtypen zu erben. Die Vererbung gilt nur bis zu einem gewissen Grad für Super-Class-Initialisierer, der unter Vererbung von automatischen Initialisierern erläutert wird.
Wenn für den Benutzer Initialisierer in der Superklasse definiert sein müssen, muss der Benutzer eine Unterklasse mit Initialisierern als benutzerdefinierte Implementierung definieren. Wenn das Überschreiben durch die Unterklasse erfolgen soll, muss das Schlüsselwort 'override' der Superklasse deklariert werden.
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)")
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Rectangle: 4 sides
Pentagon: 5 sides
Designated und Convenience Initializer in Aktion
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)
}
}
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Planet name is: Mercury
No Planets like that: [No Planets]
Failable Initializer
Der Benutzer muss benachrichtigt werden, wenn beim Definieren einer Klasse, Struktur oder Aufzählungswerte Initialisierungsfehler auftreten. Die Initialisierung von Variablen wird manchmal aufgrund von - zu einem Fehler
- Ungültige Parameterwerte.
- Fehlen der erforderlichen externen Quelle.
- Bedingung, die verhindert, dass die Initialisierung erfolgreich ist.
Um Ausnahmen zu erfassen, die durch die Initialisierungsmethode ausgelöst werden, erstellt Swift 4 eine flexible Initialisierung mit dem Namen "Failable Initialisierer", um den Benutzer darüber zu informieren, dass beim Initialisieren der Struktur-, Klassen- oder Aufzählungselemente etwas unbemerkt bleibt. Das Schlüsselwort zum Abfangen des fehlgeschlagenen Initialisierers lautet "init?". Außerdem können fehlgeschlagene und nicht ausfallbare Initialisierer nicht mit denselben Parametertypen und -namen definiert werden.
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")
}
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Student name is specified
Student name is left blank
Verfügbare Initialisierer für Aufzählungen
Die Sprache Swift 4 bietet die Flexibilität, Failable-Initialisierer auch für Aufzählungen zu haben, um den Benutzer zu benachrichtigen, wenn die Aufzählungsmitglieder keine Werte mehr initialisieren können.
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")
}
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
With In Block Two
Block Does Not Exist
Verfügbare Initialisierer für Klassen
Ein fehlgeschlagener Initialisierer, der mit Aufzählungen und Strukturen deklariert wird, warnt unter allen Umständen innerhalb seiner Implementierung einen Initialisierungsfehler. Ein fehlgeschlagener Initialisierer in Klassen warnt den Fehler jedoch erst, nachdem die gespeicherten Eigenschaften auf einen Anfangswert festgelegt wurden.
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)")
}
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Module is Optional("Failable Initializers")
Überschreiben eines fehlgeschlagenen Initialisierers
Wie beim Initialisieren hat der Benutzer auch die Möglichkeit, einen fehlgeschlagenen Initialisierer der Oberklasse innerhalb der Unterklasse zu überschreiben. Die fehlgeschlagene Initialisierung der Superklasse kann auch in einem nicht fehlgeschlagenen Initialisierer der Unterklasse überschrieben werden.
Der Unterklasseninitialisierer kann nicht an den Superklasseninitialisierer delegieren, wenn ein fehlgeschlagener Superklasseninitialisierer mit einer nicht ausfallbaren Unterklasseninitialisierung überschrieben wird.
Ein nicht fehlgeschlagener Initialisierer kann niemals an einen fehlerhaften Initialisierer delegieren.
Das unten angegebene Programm beschreibt die fehlgeschlagenen und nicht ausfallbaren Initialisierer.
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)
}
}
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Planet name is: Mercury
No Planets like that: [No Planets]
Der Init! Failable Initializer
Swift 4 bietet 'init?' um einen optionalen fehlgeschlagenen Instanzinitialisierer zu definieren. Definieren einer implizit entpackten optionalen Instanz des spezifischen Typs 'init!' angegeben.
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")
}
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
Student name is specified
Student name is left blank
Erforderliche Initialisierer
Um jede Unterklasse des Schlüsselworts "Initialisieren" erforderlich zu deklarieren, muss sie vor der Funktion init () definiert werden.
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()
Wenn wir das obige Programm auf einem Spielplatz ausführen, erhalten wir das folgende Ergebnis:
10
30
10