Swift - Initialisation
Les classes, structures et énumérations une fois déclarées dans Swift 4 sont initialisées pour préparer l'instance d'une classe. La valeur initiale est initialisée pour la propriété stockée et également pour les nouvelles instances, les valeurs sont initialisées pour continuer. Le mot-clé pour créer la fonction d'initialisation est exécuté par la méthode 'init ()'. L'initialiseur Swift 4 diffère d'Objective-C en ce qu'il ne renvoie aucune valeur. Sa fonction est de vérifier l'initialisation des instances nouvellement créées avant son traitement. Swift 4 fournit également un processus de «désinitialisation» pour effectuer des opérations de gestion de la mémoire une fois que les instances sont désallouées.
Rôle d'initialisation pour les propriétés stockées
Les propriétés stockées doivent initialiser les instances de ses classes et structures avant de traiter les instances. Les propriétés stockées utilisent un initialiseur pour affecter et initialiser des valeurs, éliminant ainsi le besoin d'appeler des observateurs de propriétés. L'initialiseur est utilisé dans la propriété stockée
Pour créer une valeur initiale.
Pour attribuer une valeur de propriété par défaut dans la définition de propriété.
Pour initialiser une instance pour un type de données particulier, «init ()» est utilisé. Aucun argument n'est passé dans la fonction init ().
Syntaxe
init() {
//New Instance initialization goes here
}
Exemple
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area of rectangle is 72.0
Ici, la structure «rectangle» est initialisée avec la longueur et la largeur des membres en tant que types de données «Double». La méthode Init () est utilisée pour initialiser les valeurs pour la longueur et le double des membres nouvellement créés. L'aire du rectangle est calculée et renvoyée en appelant la fonction rectangle.
Définition des valeurs de propriété par défaut
Le langage Swift 4 fournit la fonction Init () pour initialiser les valeurs de propriété stockées. En outre, l'utilisateur a la possibilité d'initialiser les valeurs de propriété par défaut lors de la déclaration des membres de la classe ou de la structure. Lorsque la propriété prend la même valeur seule dans tout le programme, nous pouvons la déclarer uniquement dans la section déclaration plutôt que de l'initialiser dans init (). La définition des valeurs de propriété par défaut active l'utilisateur lorsque l'héritage est défini pour les classes ou les structures.
struct rectangle {
var length = 6
var breadth = 12
}
var area = rectangle()
print("area of rectangle is \(area.length*area.breadth)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area of rectangle is 72
Ici, au lieu de déclarer la longueur et la largeur dans init (), les valeurs sont initialisées dans la déclaration elle-même.
Initialisation des paramètres
En langage Swift 4, l'utilisateur a la possibilité d'initialiser les paramètres dans le cadre de la définition de l'initialiseur en utilisant 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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: 72.0
area is: 432.0
Paramètres locaux et externes
Les paramètres d'initialisation ont des noms de paramètres locaux et globaux similaires à ceux des paramètres de fonction et de méthode. La déclaration de paramètre local est utilisée pour accéder dans le corps d'initialisation et la déclaration de paramètre externe est utilisée pour appeler l'initialiseur. Les initialiseurs Swift 4 diffèrent de l'initialiseur de fonction et de méthode en ce qu'ils n'identifient pas quel initialiseur est utilisé pour appeler quelles fonctions.
Pour surmonter cela, Swift 4 introduit un nom externe automatique pour chaque paramètre dans init (). Ce nom externe automatique est aussi équivalent que le nom local écrit avant chaque paramètre d'initialisation.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
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
Paramètres sans noms externes
Lorsqu'un nom externe n'est pas nécessaire pour un trait de soulignement d'initialisation, «_» est utilisé pour remplacer le comportement par défaut.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: 180.0
area is: 370.0
area is: 110.0
Types de propriété facultatifs
Lorsque la propriété stockée à une instance ne renvoie aucune valeur, cette propriété est déclarée avec un type «facultatif» indiquant qu'aucune valeur n'est renvoyée pour ce type particulier. Lorsque la propriété stockée est déclarée comme «facultative», elle initialise automatiquement la valeur à «nil» lors de l'initialisation elle-même.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
Modification des propriétés des constantes lors de l'initialisation
L'initialisation permet également à l'utilisateur de modifier également la valeur de la propriété constante. Lors de l'initialisation, la propriété de classe permet à ses instances de classe d'être modifiées par la super classe et non par la sous-classe. Considérez par exemple dans le programme précédent que «longueur» est déclarée comme «variable» dans la classe principale. La variable de programme ci-dessous «longueur» est modifiée comme variable «constante».
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
Initialiseurs par défaut
Les initialiseurs par défaut fournissent une nouvelle instance à toutes ses propriétés déclarées de classe de base ou de structure avec des valeurs par défaut.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant le terrain de jeu, nous obtenons le résultat suivant. -
result is: nil
result is: 98
result is: true
Le programme ci-dessus est défini avec le nom de classe «defaultexample». Trois fonctions membres sont initialisées par défaut en tant que 'studname?' pour stocker les valeurs «nil», «stmark» comme 98 et «pass» comme valeur booléenne «true». De même, les valeurs de membre de la classe peuvent être initialisées par défaut avant de traiter les types de membre de classe.
Initialiseurs Memberwise pour les types de structure
Lorsque les initialiseurs personnalisés ne sont pas fournis par l'utilisateur, les types de structure dans Swift 4 recevront automatiquement l '«initialiseur par membre». Sa fonction principale est d'initialiser les nouvelles instances de structure avec l'initialisation par défaut des membres, puis les nouvelles propriétés d'instance sont transmises à l'initialisation des membres par leur nom.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Area of rectangle is: 24.0
Area of rectangle is: 32.0
Les structures sont initialisées par défaut pour leurs fonctions d'appartenance lors de l'initialisation pour «longueur» comme «100,0» et «largeur» comme «200,0». Mais les valeurs sont remplacées lors du traitement des variables longueur et largeur comme 24,0 et 32,0.
Délégation d'initialiseur pour les types de valeur
La délégation d'initialisation est définie comme l'appel d'initialiseurs à partir d'autres initialiseurs. Sa fonction principale est d'agir en tant que réutilisabilité pour éviter la duplication de code entre plusieurs initialiseurs.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)
Règles de délégation d'initialiseur
Types de valeur | Types de classe |
---|---|
L'héritage n'est pas pris en charge pour les types valeur tels que les structures et les énumérations. La référence à d'autres initialiseurs se fait via self.init | L'héritage est pris en charge. Vérifie que toutes les valeurs de propriété stockées sont initialisées |
Héritage et initialisation de classe
Les types de classe ont deux types d'initialiseurs pour vérifier si les propriétés stockées définies reçoivent une valeur initiale, à savoir les initialiseurs désignés et les initialiseurs pratiques.
Initialiseurs désignés et initialiseurs de commodité
Initialiseur désigné | Initialiseur de commodité |
---|---|
Considéré comme l'initialisation principale d'une classe | Considéré comme supportant l'initialisation pour une classe |
Toutes les propriétés de classe sont initialisées et un initialiseur de superclasse approprié est appelé pour une initialisation supplémentaire | Un initialiseur désigné est appelé avec un initialiseur pratique pour créer une instance de classe pour un cas d'utilisation spécifique ou un type de valeur d'entrée |
Au moins un initialiseur désigné est défini pour chaque classe | Pas besoin d'avoir des initialiseurs de commodité obligatoires définis lorsque la classe ne nécessite pas d'initialiseurs. |
Init (paramètres) {instructions} | commodité init (paramètres) {instructions} |
Programme pour les initialiseurs désignés
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 10
res is: 10
res is: 20
Programme pour les initialiseurs de commodité
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 20
res is: 30
res is: 50
Héritage et remplacement de l'initialiseur
Swift 4 ne permet pas à ses sous-classes d'hériter par défaut de ses initialiseurs de superclasse pour leurs types de membres. L'héritage n'est applicable aux initialiseurs de super classe que dans une certaine mesure, ce qui sera discuté dans Héritage d'initialisation automatique.
Lorsque l'utilisateur a besoin d'avoir des initialiseurs définis dans la super classe, la sous-classe avec les initialiseurs doit être définie par l'utilisateur comme une implémentation personnalisée. Lorsque le remplacement doit être effectué par la sous-classe, le mot-clé «override» de la super classe doit être déclaré.
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)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Rectangle: 4 sides
Pentagon: 5 sides
Initialiseurs désignés et pratiques en action
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)
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Planet name is: Mercury
No Planets like that: [No Planets]
Initialiseur disponible
L'utilisateur doit être averti en cas d'échec de l'initialisation lors de la définition d'une classe, d'une structure ou de valeurs d'énumération. L'initialisation des variables devient parfois un échec en raison de -
- Valeurs de paramètre non valides.
- Absence de source externe requise.
- Condition empêchant l'initialisation de réussir.
Pour intercepter les exceptions levées par la méthode d'initialisation, Swift 4 produit une initialisation flexible appelée «initialiseur failable» pour informer l'utilisateur que quelque chose est laissé inaperçu lors de l'initialisation de la structure, de la classe ou des membres de l'énumération. Le mot clé pour attraper l'initialiseur disponible est «init?». De plus, les initialiseurs disponibles et non disponibles ne peuvent pas être définis avec les mêmes types et noms de paramètres.
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")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student name is specified
Student name is left blank
Initialiseurs disponibles pour les énumérations
Le langage Swift 4 offre la flexibilité d'avoir des initialiseurs disponibles pour les énumérations afin d'avertir l'utilisateur lorsque les membres de l'énumération sont laissés de l'initialisation des valeurs.
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")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
With In Block Two
Block Does Not Exist
Initialiseurs disponibles pour les classes
Un initialiseur disponible lorsqu'il est déclaré avec des énumérations et des structures alerte un échec d'initialisation en toute circonstance au sein de son implémentation. Cependant, l'initialiseur disponible dans les classes n'alertera l'échec qu'une fois que les propriétés stockées auront été définies sur une valeur initiale.
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)")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Module is Optional("Failable Initializers")
Remplacement d'un initialiseur disponible
Comme pour initialize, l'utilisateur a également la possibilité de remplacer un initialiseur disponible de superclasse à l'intérieur de la sous-classe. L'initialisation disponible de la super classe peut également être remplacée par un initialiseur de sous-classe non disponible.
L'initialiseur de sous-classe ne peut pas déléguer jusqu'à l'initialiseur de superclasse lors du remplacement d'un initialiseur de superclasse disponible avec une initialisation de sous-classe non disponible.
Un initialiseur non disponible ne peut jamais déléguer à un initialiseur disponible.
Le programme ci-dessous décrit les initialiseurs disponibles et non disponibles.
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)
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Planet name is: Mercury
No Planets like that: [No Planets]
L'init! Initialiseur disponible
Swift 4 fournit «init?» pour définir un initialiseur facultatif d'instance disponible. Pour définir une instance facultative implicitement déroulée du type spécifique 'init!' est spécifié.
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")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student name is specified
Student name is left blank
Initialiseurs requis
Pour déclarer chaque sous-classe du mot clé initialize 'required' doit être défini avant la fonction 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()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
10
30
10