Init
init
is a keyword in Swift. It it shorthand for “initialization.”
It is used to designate a special type of instance method in classes, structs, and enums.
This special instance method has one goal: to make the instance ready to use.
We can say the init
method “initializes an instance of a class/struct/enum”.
In its most basic form, an init
method looks like this:
func init() { ... }
Within the init
method, you setup everything you need to setup before this instance is ready to be used.
In this example, we have a class with a stored property. Inside the init
we need to set the value for the stored property, so an instance of this class is “ready to use.”
class CraftBeer {
let name: String
init() {
name = "Super Hoppy IPA"
}
}
Designated Init
The main initializer for a class is called a designated initializer. This designated initializer does all of the setup necessary to make an instance of this class ready to be used.
Classes usually have only one of these, but they can have more.
Every class must have at least one designated initializer.
In the example CraftBeer
, the init
we have already seen is considered the designated initializer:
class CraftBeer {
let name: String
// Designated initializer
init() {
name = "Super Hoppy IPA"
}
}
Convenience Init
convenience
is a modifier in Swift that we can add before our init
method.
convenience init() { ... }
A convenience init
is not the main init
for a class.
Its goal is to do some custom setup, and then call the designated init
to finish the job.
init() { ... }
convenience init() {
// Perform some custom setup
// Call the designated init
self.init()
}
The goal of a convenience init
is to provide a more “convenient” way to initialize a class. This is useful when the designated init
is large and complex.
Imagine in our app that uses the class CraftBeer
, a user can add a new beer to a list of beers. Each beer has a name, brewery, beer style, and alcohol percentage:
class CraftBeer {
let name: String
let brewery: String
let style: String
let alcoholPercentage: Double?
// Designated init
init(name: String, brewery: String, style: String, alcoholPercentage: Double?) {
self.name = name
self.brewery = brewery
self.style = style
self.alcoholPercentage = alcoholPercentage
}
}
Sometimes the user knows all of the information about the CraftBeer
and sometimes, the user knows only the name of the beer. We want the user to be able to save this new beer even if s/he only knows the name.
To do this, we create a convenience init
with only one argument: name. Then we set default values for the rest of the properties, and call the designated init
to finish the initialization:
class CraftBeer {
let name: String
let brewery: String
let style: String
let alcoholPercentage: Double?
// Designated init
init(name: String, brewery: String, style: String, alcoholPercentage: Double?) {
self.name = name
self.brewery = brewery
self.style = style
self.alcoholPercentage = alcoholPercentage
}
convenience init(name: String) {
self.init(name: name, brewery: "Unknown", style: "Unknown", alcoholPercentage: nil))
}
}
Later, the user can go back and add the rest of the information about this beer.