Swift Initializers
Have you ever stopped to think about why you do what you do? I think it happens with all of us, at different levels, of course. In iOS development it can happen too. You write some code, just for the sake of writing, and then ask yourself: why?
That’s what used to happen regarding initializers for me. I would write only because I know I had to, or because the compiler told me to do so. So I decided to do a bit of research, in order to understand a bit better about them. I will share my findings in this article.
So, going straight to the point. According to Apple docs:
Initialization is the process of preparing an instance of a class, structure, or enumeration for use.
They are methods that can be called to create a new instance of a type. They ensure the new instances are ready to be used for the first time.
The basics
It’s possible to set a value of a stored property within an initializer, or by assigning a default value.
Let’s say we have a Meal
class, for example. A meal is composed by carbohydrate (abbreviated to carb), fat and protein. We can declare those properties, but they do not have a default value. Which means that we need to provide a proper initialization to our class.
So we declare the keyword init()
that takes as parameters carb, fat and protein, and within the method we set the received values to our stored properties.
Here’s how the code looks like:
Now we are making sure that every time an instance of Meal
is created, it should require an initializer with those properties.
We can have more than one initializer for the same type. And it’s worth mentioning that they have no function names to differentiate them, so what makes them different are their parameters.
Designated Initializers and Convenience Initializers
The designated and convenience initializers are designed to ensure all properties of a class receive a value, including any properties inherited from its superclass.
Designated initializers are the main initializers of a class. They fully initialize all the properties needed and call a superclass initializer to continue the initialization process.
Every class must have at least one designated initializer.
It could be a Default Initializer, provided by swift when the class or structure provides default values for all its properties and does not provide an explicit initializer , like this:
Or it could be an Automatically Inherited Initializer, which happens in two scenarios:
- A subclass has no designated initializers.
- A subclass implements all of their superclass initializers, either via the first rule, or by providing a custom implementation as part of its definition.
Convenience initializers, on the other hand, are the secondary initializers. They are not required, unless your class needs it, and they must call designated initializers, either from the same class or from its superclass.. They can do it using default values, or attributing new values. Also, they can be created in a class to support a specific use case.
Now, let’s take a look at another example using our Cake class. When defining its properties, we could create a convenience initializers, in case we wanted a default value for one of the properties (in this case we want to set a default value for the sugar property, so our cake doesn’t end up too sweet). Then, we might end up with a code similar to this:
Then, we can instantiate our cake using both initialisers, according to our needs.
Wrapping up
This article showed the basics about swift initializers and a few ways in which they can be used. Of course, it’s such a huge topic and there’s much to cover and a lot more that we can do with them, but hopefully this will give you an idea about the subject, as it also helped me to understand it better.
If you want to know more, I will leave a few useful articles linked here, as well as Apple’s official documentation.
Initialization - The Swift Programming Language (Swift 5.1)