When preparing for iOS interviews, it’s crucial to focus on Swift initializers
, as they often become key discussion points. Being well-prepared for these questions is essential, as they are commonly asked and can significantly contribute to your success in iOS interviews.
Initializer in swift
An initializer in Swift is a special method used to set up an instance of a class, struct, or enum.
It prepares the instance by setting initial values for its properties and performing any other necessary setup.
Initializers are essential because they ensure that an object is fully and correctly initialized before it is used.
Initializers are called to create a new instance of a particular type. In its simplest form, an initializer is like an instance method with no parameters, written using the init keyword:
init() { // perform some initialization here }
Swift provides several types of initializers, including default initializers, designated initializers, convenience initializers, required initializers, and more. Here are detailed explanations and code examples for each kind:
Default Initializers
if you have a structure or class where all the properties have default values, and you haven’t provided any custom initializers, Swift automatically gives you a default initializer.
This built-in initializer creates a new instance with all the properties set to their default values.
This example defines a class called Shopping
, which encapsulates the name, quantity, and purchase state of an item in a shopping list:
class ShoppingListItem { var name: String? var quantity = 1 var purchased = false } var item = ShoppingListItem()
Because all properties of the Shopping
class have default values, and because it’s a base class with no superclass, Shopping
automatically gains a default initializer implementation that creates a new instance with all of its properties set to their default values. (The name
property is an optional String
property, and so it automatically receives a default value of nil
, even though this value isn’t written in the code.) The example above uses the default initializer for the Shopping
class to create a new instance of the class with initializer syntax, written as Shopping
, and assigns this new instance to a variable called item
.
Memberwise Initializers
Memberwise initializers in Swift are automatically generated initializers for structures. These initializers are provided by the Swift compiler and allow you to initialize a structure’s properties by specifying values for each property during instance creation.
When you create a struct
in Swift and list its properties, Swift automatically creates a memberwise initializer for you. This initializer conveniently takes parameters labeled with the same names as the struct’s properties, making it easier to initialize instances by providing values for each property.
For example, if you have a struct
called Point
with properties x
and y
, Swift generates a memberwise initializer like this:
Example:
struct Point { var x: Double var y: Double } // Swift generates a memberwise initializer like this: let point = Point(x: Double, y: Double)
In this example, the Point
structure has two properties (x
and y
). Because there are no custom initializers in its declaration, Swift automatically generates a memberwise initializer. You can create an instance of Point
by providing values for x
and y
during initialization.
When we try to initialize Point struct, Xcode will display list of suggestions including memberwise initializer.
Memberwise initializers are only available for structures, not for classes.
Unlike a default initializer, the structure receives a memberwise initializer even if it has stored properties that don’t have default values.
Designated Initializers and Convenience Initializers
Swift defines two kinds of initializers for class types to help ensure all stored properties receive an initial value. These are known as designated initializers and convenience initializers.
Designated Initializers
Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class.
Every class must have at least one designated initializer.
class Person { var name: String var age: Int // Designated initializer init(name: String, age: Int) { self.name = name self.age = age } } let person = Person(name: "John", age: 30) print(person.name) // Output: John print(person.age) // Output: 30
Convenience Initializers
Convenience initializers are secondary, supporting initializers that must call a designated initializer from the same class.
They are typically used to provide default values or simplify initialization.
class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } // Convenience initializer convenience init() { self.init(name: "Unknown", age: 0) } } let person = Person() print(person.name) // Output: Unknown print(person.age) // Output: 0
FAQs
Q. When is a memberwise initializer not available?
Ans. The compiler only generates a memberwise initializer for a struct
if the struct
doesn’t define any custom initializer(s). When you define a custom initializer in your struct
, it replaces the default memberwise
initializer.
Example-
struct Point { var x: Double var y: Double init(point: (Double, Double)) { self.x = point.0 self.y = point.1 } }
If we check Xcode’s list of suggestions for this struct Point
we don’t get memberwise
initializer anymore. The only option we have to create a Point
struct is the custom initializer we defined.
Q. Can we use default memberwise initializer along with custom initializer?
Ans. Yes, we can use default memberwise initializer along with custom initializer. We can achive this by defining the custom initializer in an extension for the struct.
Example-
struct Point { var x: Double var y: Double } extension Point { init(point: (Double, Double)) { self.x = point.0 self.y = point.1 } }
If we check Xcode’s list of suggestions for this struct Point
we can find memberwise
initializer along with custom one.
Q. Why don’t Swift classes have a memberwise initializer?
Ans. In Swift, structures automatically receive a memberwise
initializer by default, which initializes all their properties. This memberwise
initializer is provided by the Swift compiler and allows you to create an instance of a struct
and set its properties in one go.
However, classes in Swift do not automatically receive a memberwise
initializer. The primary reason for this is that classes in Swift have inheritance
, and their initialization process is more complex than that of structs. Classes can have designated
initializers, convenience
initializers, and can also participate in inheritance
chains. Automatic generation of a memberwise
initializer for classes would not fit well into this more complex initialization model.
When you define a class in Swift, you can create your own initializers to suit the specific needs of the class. This gives you more control over the initialization process, allowing you to ensure that the object is set up correctly and that any necessary initialization steps are performed.
Example-
Suppose we have a base class called Person
:
class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } }
Now, let’s create a subclass called Employee
:
class Employee: Person { var employeeID: String // Compiler-generated memberwise initializer would be problematic here }
Now, let’s say you have code that uses the memberwise initializer for Employee
:
let employee = Employee(name: "Sim", age: 20, employeeID: "E2111")
Later on, someone modifies the base class Person
to include a new property:
class Person { var name: String var age: Int var address: String // New property init(name: String, age: Int, address: String) { self.name = name self.age = age self.address = address } }
With the automatic memberwise initializer, the Employee
class would break because the generated initializer doesn’t account for the new address
property in the base class.
By not automatically generating memberwise initializers for classes, Swift avoids such scenarios, and developers need to explicitly define initializers, making them aware of the changes in the class hierarchy.
Read More