DEV Community

Ajithmadhan
Ajithmadhan

Posted on

Swift - Initializer & Deinitializer

An initializer is a special type of function that is used to create an object of a class or struct.

In Swift, we use the init() method to create an initializer. For example,

struct Fahrenheit {
    var temperature: Double
    init() {
        temperature = 32.0
    }
}

var f = Fahrenheit()
f.temperature //32.0
Enter fullscreen mode Exit fullscreen mode

Parameterized Initializer

A Swift initializer can also accept one or more parameters. Such initializers are known as parameterized initializers (initializers with parameters).

struct Fahrenheit {
    var temperature: Double
    init(temp:Double) {
        self.temperature = temp
    }
}

var f = Fahrenheit(temp:45)
f.temperature //45.0
Enter fullscreen mode Exit fullscreen mode

Parameter Names and Argument Labels

As with function and method parameters, initialization parameters can have both a parameter name for use within the initializer’s body and an argument label for use when calling the initializer.

struct Color {
    let red, green, blue: Double
    init(red: Double, green: Double, blue: Double) {
        self.red   = red
        self.green = green
        self.blue  = blue
    }
    init(white: Double) {
        red   = white
        green = white
        blue  = white
    }

let magenta = Color(red: 1.0, green: 0.0, blue: 1.0)
let halfGray = Color(white: 0.5)

Enter fullscreen mode Exit fullscreen mode

If you don’t want to use an argument label for an initializer parameter, write an underscore (_) instead of an explicit argument label for that parameter to override the default behavior.

Optional Property Types

If your custom type has a stored property that’s logically allowed to have “no value”—perhaps because its value can’t be set during initialization, or because it’s allowed to have “no value” at some later point—declare the property with an optional type.

class SurveyQuestion {
    var text: String
    var response: String?
    init(text: String) {
        self.text = text
    }
    func ask() {
        print(text)
    }
}
let cheeseQuestion = SurveyQuestion(text: "Do you like cheese?")
cheeseQuestion.ask()
// Prints "Do you like cheese?"
Enter fullscreen mode Exit fullscreen mode

Initializer Overloading

Swift Initializers can be overloaded in a similar way as function overloading.

In initializer overloading, two or more initializers can have the same name if they have different types or numbers of parameters.

And, based on the arguments passed during the object creation, the corresponding initializer is called.

class Person {
  var age: Int

  // 1. initializer with no arguments
  init() {
    age = 20
  }

  // 2. initializer with an argument
  init(age: Int) {
    self.age = age
  }

  // method to return age
  func getAge() -> Int {
    return age
  }
}

var person1 = Person()
var person2 = Person(age: 23)

print("Person1 Age:", person1.getAge())
print("Person1 Age:", person2.getAge())
Enter fullscreen mode Exit fullscreen mode

Swift convenience Initializer

In previous examples, the initializer we defined were primary initializers of the class. These primary initializers are also called designated initializers.

However, we can also define a secondary/supporting initializer for a class called convenience initializer.

To define a convenience initializer, we use the convenience keyword before the initializer. For example,

class University {

  var name : String
  var rank : String

  init(name : String, rank: String) {
    self.name = name
    self.rank = rank
  }

  // define convenience init  
  convenience init() {
    self.init(name: "Kathmandu University", rank: "1st")
  }

}

var university1 = University()
//convenience init is called
print(university1.name)
print("Rank:", university1.rank)

Enter fullscreen mode Exit fullscreen mode

Failable Initializer

In some cases initializers might or might not work, this is called a failable initializer.

We write a failable initializer by placing a question mark (?) after the init keyword and return nil if something goes wrong.

class File {

  var folder: String

  // failable initializer
  init?(folder: String) {

    // check if empty
    if folder.isEmpty {
      print("Folder Not Found") // 1st output
      return nil
    }
    self.folder = folder
  }
}

// create folder1 object
var file  = File(folder: "")
if (file != nil) {
  print("File Found Successfully")
}
else {
  print("Error Finding File") // 2nd output
}
Enter fullscreen mode Exit fullscreen mode

Refer docs for in-depth explanation of this concept.
swift-Initializer

Deinitialization

A deinitializer is called immediately before a class instance is deallocated. You write deinitializers with the deinit keyword, similar to how initializers are written with the init keyword. Deinitializers are only available on class types.

deinit {
    // perform the deinitialization
}
Enter fullscreen mode Exit fullscreen mode

Swift automatically deallocates your instances when they’re no longer needed, to free up resources. Swift handles the memory management of instances through automatic reference counting ARC (Automatic Reference Counting). Typically you don’t need to perform manual cleanup when your instances are deallocated. However, when you are working with your own resources, you might need to perform some additional cleanup yourself. For example, if you create a custom class to open a file and write some data to it, you might need to close the file before the class instance is deallocated.

Top comments (0)