Initialization and Deinitialization

16.1 Struct Initializers

struct Temperature {
    var celsius: Double

    init(celsius: Double) { self.celsius = celsius }
    init(fahrenheit: Double) { celsius = (fahrenheit - 32) * 5 / 9 }
    init?(text: String) {                          // failable initializer
        guard let value = Double(text) else { return nil }
        celsius = value
    }
}
// Custom inits in an extension keep the memberwise initializer available

16.2 Class Initializers: Designated and Convenience

Must call a designated init of the superclass Must call another init of the same class, ultimately a designated one

Phase 1: all stored properties get values (bottom-up). Phase 2: customization (top-down).

required init Every subclass must implement it (e.g., init(coder:)) Failable init? / init! May return nil Throwing init() throws May throw errors

class Food {
    var name: String
    init(name: String) { self.name = name }              // designated
    convenience init() { self.init(name: "[Unnamed]") }  // convenience → calls a designated init
}

class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity          // phase 1: initialize own properties FIRST
        super.init(name: name)            // then delegate up
        // phase 2: can now use self and call methods
    }
    override convenience init(name: String) { self.init(name: name, quantity: 1) }
}

class ShoppingItem: RecipeIngredient {
    var purchased = false                 // a default value means all inits are inherited
}

16.3 Deinitialization

class FileHandleWrapper {
    let path: String
    init(path: String) { self.path = path; print("open \(path)") }
    deinit { print("close \(path)") }      // runs when the last strong reference goes away
}
do { let f = FileHandleWrapper(path: "a.txt") }   // "open a.txt" then "close a.txt"