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 available16.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"