Initialization in Swift


Introduction to Initialization in Swift

In Swift, initialization is the process of preparing an instance of a class, structure, or enumeration before it is used. During initialization, properties are assigned initial values, and any necessary setup is performed. Swift ensures that all stored properties are initialized before an instance is used, improving safety and reliability.

Swift provides default initializers, custom initializers, convenience initializers, and failable initializers, making the process flexible and powerful.

Why is Initialization Important?


  • Ensures all properties have values before use.
  • Allows custom setup logic when creating an instance.
  • Supports default values and optional initialization.
  • Improves code safety by preventing uninitialized variables.

Basic Syntax of an Initializer

struct StructName {
     var property: Type

     init(parameter: Type) {
         self.property = parameter
     }
}

Types of Initializers in Swift


1. Default Initializer (Auto-Generated)

Swift automatically generates a default initializer if all properties have default values.

struct Car {
     var brand: String = "Tesla"
     var model: String = "Model 3"
}

let myCar = Car() // No need to manually initialize
print(myCar.brand) // Tesla

Output


Tesla

2. Memberwise Initializer (For Structs)

Structures automatically get a memberwise initializer when no custom initializer is defined.

struct Laptop {
     var brand: String
     var ram: Int
}

let myLaptop = Laptop(brand: "Apple", ram: 16)
print(myLaptop.brand) // Apple

Output


Apple

Note: Classes do not get a memberwise initializer by default.

3. Custom Initializer (Using init)

class Person {
     var name: String
     var age: Int

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

     func display() {
         print("Name: \(name), Age: \(age)")
     }
}

let person1 = Person(name: "Alice", age: 25)
person1.display()

Output


Name: Alice, Age: 25

4. Initializer with Default Parameter Values

struct Rectangle {
     var width: Double
     var height: Double

     init(width: Double = 10, height: Double = 5) {
         self.width = width
         self.height = height
     }
}

let rect1 = Rectangle() // Uses default values
let rect2 = Rectangle(width: 15, height: 7)

print(rect1.width) // 10
print(rect2.width) // 15

Output


10.0
15.0

5. Convenience Initializer (For Classes Only)

Convenience initializers provide additional initialization logic while calling a designated initializer.

class User {
     var username: String
     var email: String

     init(username: String, email: String) {
         self.username = username
         self.email = email
     }

     convenience init(username: String) {
         self.init(username: username, email: "\(username)@example.com")
     }
}

let user1 = User(username: "john_doe")
print(user1.email) // john_doe@example.com

Output


john_doe@example.com

6. Failable Initializer (init?)

A failable initializer returns nil if initialization fails.

struct Product {
     var name: String
     var price: Double

     init?(name: String, price: Double) {
         if price < 0 { return nil } // Invalid price
         self.name = name
         self.price = price
     }
}

if let product = Product(name: "Laptop", price: -100) {
     print("Product created")
} else {
     print("Invalid product")
}

Output


Invalid product

7. Required Initializer (required init)

A required initializer ensures that all subclasses implement the same initializer.

class Animal {
     var name: String

     required init(name: String) {
         self.name = name
     }
}

class Dog: Animal {
     required init(name: String) {
         super.init(name: name)
     }
}



8. Deinitializer (deinit)

A deinitializer (deinit) runs just before an instance is deallocated. Only classes have deinitializers.

class FileManager {
     let fileName: String

     init(fileName: String) {
         self.fileName = fileName
         print("\(fileName) opened")
     }

     deinit {
         print("\(fileName) closed")
     }
}

var file: FileManager? = FileManager(fileName: "document.txt")
file = nil // Object deallocated, deinit called

Output

document.txt opened
document.txt closed