English 中文(简体)
Swift - Initialization
  • 时间:2024-09-17

Swift - Initiapzation


Previous Page Next Page  

Classes, structures and enumerations once declared in Swift 4 are initiapzed for preparing instance of a class. Initial value is initiapzed for stored property and also for new instances too the values are initiapzed to proceed further. The keyword to create initiapzation function is carried out by init() method. Swift 4 initiapzer differs from Objective-C that it does not return any values. Its function is to check for initiapzation of newly created instances before its processing. Swift 4 also provides deinitiapzation process for performing memory management operations once the instances are deallocated.

Initiapzer Role for Stored Properties

Stored property have to initiapze the instances for its classes and structures before processing the instances. Stored properties use initiapzer to assign and initiapze values thereby eradicating the need to call property observers. Initiapzer is used in stored property

    To create an initial value.

    To assign default property value within the property definition.

    To initiapze an instance for a particular data type init() is used. No arguments are passed inside the init() function.

Syntax

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

Example

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

When we run the above program using playground, we get the following result −

area of rectangle is 72.0

Here the structure rectangle is initiapzed with members length and breadth as Double datatypes. Init() method is used to initiapze the values for the newly created members length and double. Area of rectangle is calculated and returned by calpng the rectangle function.

Setting Property Values by Default

Swift 4 language provides Init() function to initiapze the stored property values. Also, the user has provision to initiapze the property values by default while declaring the class or structure members. When the property takes the same value alone throughout the program we can declare it in the declaration section alone rather than initiapzing it in init(). Setting property values by default enables the user when inheritance is defined for classes or structures.

struct rectangle {
   var length = 6
   var breadth = 12
}

var area = rectangle()
print("area of rectangle is (area.length*area.breadth)")

When we run the above program using playground, we get the following result −

area of rectangle is 72

Here instead of declaring length and breadth in init() the values are initiapzed in declaration itself.

Parameters Initiapzation

In Swift 4 language the user has the provision to initiapze parameters as part of the initiapzer s definition using 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)")

When we run the above program using playground, we get the following result −

area is: 72.0
area is: 432.0

Local & External Parameters

Initiapzation parameters have both local and global parameter names similar to that of function and method parameters. Local parameter declaration is used to access within the initiapze body and external parameter declaration is used to call the initiapzer. Swift 4 initiapzers differ from function and method initiapzer that they do not identify which initiapzer are used to call which functions.

To overcome this, Swift 4 introduces an automatic external name for each and every parameter in init(). This automatic external name is as equivalent as local name written before every initiapzation parameter.

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

When we run the above program using playground, we get the following result −

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

Parameters without External Names

When an external name is not needed for an initiapze underscore _ is used to override the default behavior.

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

When we run the above program using playground, we get the following result −

area is: 180.0
area is: 370.0
area is: 110.0

Optional Property Types

When the stored property at some instance does not return any value that property is declared with an optional type indicating that no value is returned for that particular type. When the stored property is declared as optional it automatically initiapzes the value to be nil during initiapzation itself.

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

When we run the above program using playground, we get the following result −

area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)

Modifying Constant Properties During Initiapzation

Initiapzation also allows the user to modify the value of constant property too. During initiapzation, class property allows its class instances to be modified by the super class and not by the subclass. Consider for example in the previous program length is declared as variable in the main class. The below program variable length is modified as constant variable.

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

When we run the above program using playground, we get the following result −

area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)

Default Initiapzers

Default initiapzers provide a new instance to all its declared properties of base class or structure with default values.

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

When we run above program using playground, we get following result. −

result is: nil
result is: 98
result is: true

The above program is defined with class name as defaultexample . Three member functions are initiapzed by default as studname? to store nil values, stmark as 98 and pass as Boolean value true . Likewise the member values in the class can be initiapzed as default before processing the class member types.

Memberwise Initiapzers for Structure Types

When the custom initiapzers are not provided by the user, Structure types in Swift 4 will automatically receive the memberwise initiapzer . Its main function is to initiapze the new structure instances with the default memberwise initiapze and then the new instance properties are passed to the memberwise initiapze by name.

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

When we run the above program using playground, we get the following result −

Area of rectangle is: 24.0
Area of rectangle is: 32.0

Structures are initiapzed by default for their membership functions during initiapzation for length as 100.0 and breadth as 200.0 . But the values are overridden during the processing of variables length and breadth as 24.0 and 32.0.

Initiapzer Delegation for Value Types

Initiapzer Delegation is defined as calpng initiapzers from other initiapzers. Its main function is to act as reusabipty to avoid code duppcation across multiple initiapzers.

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

When we run the above program using playground, we get the following result −

(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)

Rules for Initiapzer Delegation

Value Types Class Types
Inheritance is not supported for value types pke structures and enumerations. Referring other initiapzers is done through self.init Inheritance is supported. Checks all stored property values are initiapzed

Class Inheritance and Initiapzation

Class types have two kinds of initiapzers to check whether defined stored properties receive an initial value namely designated initiapzers and convenience initiapzers.

Designated Initiapzers and Convenience Initiapzers

Designated Initiapzer Convenience Initiapzer
Considered as primary initiapzes for a class Considered as supporting initiapze for a class
All class properties are initiapzed and appropriate superclass initiapzer are called for further initiapzation Designated initiapzer is called with convenience initiapzer to create class instance for a specific use case or input value type
At least one designated initiapzer is defined for every class No need to have convenience initiapzers compulsory defined when the class does not require initiapzers.
Init(parameters) { statements } convenience init(parameters) { statements }

Program for Designated Initiapzers

class mainClass {
   var no1 : Int // local storage
   init(no1 : Int) {
      self.no1 = no1 // initiapzation
   }
}

class subClass : mainClass {
   var no2 : Int // new subclass storage
   init(no1 : Int, no2 : Int) {
      self.no2 = no2 // initiapzation
      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)")

When we run the above program using playground, we get the following result −

res is: 10
res is: 10
res is: 20

Program for Convenience Initiapzers

class mainClass {
   var no1 : Int // local storage
   init(no1 : Int) {
      self.no1 = no1 // initiapzation
   }
}

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

When we run the above program using playground, we get the following result −

res is: 20
res is: 30
res is: 50

Initiapzer Inheritance and Overriding

Swift 4 does not allow its subclasses to inherit its superclass initiapzers for their member types by default. Inheritance is apppcable to Super class initiapzers only to some extent which will be discussed in Automatic Initiapzer Inheritance.

When the user needs to have initiapzers defined in super class, subclass with initiapzers has to be defined by the user as custom implementation. When overriding has to be taken place by the sub class to the super class override keyword has to be declared.

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

When we run the above program using playground, we get the following result −

Rectangle: 4 sides
Pentagon: 5 sides

Designated and Convenience Initiapzers in 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 pke 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)
   }
}

When we run the above program using playground, we get the following result −

Planet name is: Mercury
No Planets pke that: [No Planets]

Failable Initiapzer

The user has to be notified when there are any initiapzer failures while defining a class, structure or enumeration values. Initiapzation of variables sometimes become a failure one due to−

    Invapd parameter values.

    Absence of required external source.

    Condition preventing initiapzation from succeeding.

To catch exceptions thrown by initiapzation method, Swift 4 produces a flexible initiapze called failable initiapzer to notify the user that something is left unnoticed while initiapzing the structure, class or enumeration members. Keyword to catch the failable initiapzer is init? . Also, failable and non failable initiapzers cannot be defined with same parameter types and names.

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

When we run the above program using playground, we get the following result −

Student name is specified
Student name is left blank

Failable Initiapzers for Enumerations

Swift 4 language provides the flexibipty to have Failable initiapzers for enumerations too to notify the user when the enumeration members are left from initiapzing values.

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

When we run the above program using playground, we get the following result −

With In Block Two
Block Does Not Exist

Failable Initiapzers for Classes

A failable initiapzer when declared with enumerations and structures alerts an initiapzation failure at any circumstance within its implementation. However, failable initiapzer in classes will alert the failure only after the stored properties have been set to an initial value.

class studrecord {
   let studname: String!
   init?(studname: String) {
      self.studname = studname
      if studname.isEmpty { return nil }
   }
}

if let stname = studrecord(studname: "Failable Initiapzers") {
   print("Module is (stname.studname)")
}

When we run the above program using playground, we get the following result −

Module is Optional("Failable Initiapzers")

Overriding a Failable Initiapzer

Like that of initiapze the user also has the provision to override a superclass failable initiapzer inside the sub class. Super class failable initiapze can also be overridden with in a sub class non-failable initiapzer.

Subclass initiapzer cannot delegate up to the superclass initiapzer when overriding a failable superclass initiapzer with a non-failable subclass initiapze.

A non-failable initiapzer can never delegate to a failable initiapzer.

The program given below describes the failable and non-failable initiapzers.

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 pke 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)
   }
}

When we run the above program using playground, we get the following result −

Planet name is: Mercury
No Planets pke that: [No Planets]

The init! Failable Initiapzer

Swift 4 provides init? to define an optional instance failable initiapzer. To define an imppcitly unwrapped optional instance of the specific type init! is specified.

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

When we run the above program using playground, we get the following result −

Student name is specified
Student name is left blank

Required Initiapzers

To declare each and every subclass of the initiapze required keyword needs to be defined before the init() function.

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

When we run the above program using playground, we get the following result −

10
30
10
Advertisements