Different types of Init in Swift
In Swift, initializers are used to create new instances of a class. They come in different types: designated initializers, convenience initializers, and required initializers. Each type serves a specific purpose in the initialization process of an object. Here’s a detailed explanation of each:
Designated Initializers
- Primary Initializers: Designated initializers are the primary initializers for a class. They ensure that all properties introduced by the class are initialized.
- Initialization Chain: They call an appropriate superclass initializer to continue the initialization process up the inheritance chain.
Syntax:
class MyClass {
var property: Int
// Designated initializer
init(property: Int) {
self.property = property
// Further initialization
}
}
Convenience Initializers
- Secondary Initializers: Convenience initializers are secondary initializers. They provide additional ways to initialize a class, often with default values or simplified initialization processes.
- Must Call Another Initializer: They must call another initializer from the same class (either a designated initializer or another convenience initializer) using
self.init
. - Cannot be Overridden: They cannot be overridden by subclasses.
Syntax:
class MyClass {
var property: Int
// Designated initializer
init(property: Int) {
self.property = property
}
// Convenience initializer
convenience init() {
self.init(property: 0) // Calling designated initializer
}
}
Required Initializers
- Enforced by the Compiler: Required initializers ensure that subclasses provide an implementation of the initializer.
- Use Case: Commonly used when a class conforms to a protocol that requires specific initializers.
Syntax:
class MyClass {
var property: Int
// Designated initializer
init(property: Int) {
self.property = property
}
// Required initializer
required init?(coder aDecoder: NSCoder) {
self.property = 0
// Further initialization
}
}
class SubClass: MyClass {
// Required initializer must be implemented in subclasses
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Example with UIViewController
Let’s see how these initializers are used in the context of a custom UIViewController
:
import UIKit
class MyViewController: UIViewController {
var customTitle: String
// Designated initializer
init(customTitle: String) {
self.customTitle = customTitle
super.init(nibName: nil, bundle: nil) // Calling the designated initializer of UIViewController
}
// Required initializer (from NSCoding)
required init?(coder aDecoder: NSCoder) {
self.customTitle = "Default Title"
super.init(coder: aDecoder)
}
// Convenience initializer
convenience init() {
self.init(customTitle: "Default Title") // Calling the designated initializer
}
}
// Using the designated initializer
let vc1 = MyViewController(customTitle: "Hello, World!")
// Using the convenience initializer
let vc2 = MyViewController()
// Using the required initializer (typically used for decoding from a storyboard or nib)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc3 = storyboard.instantiateViewController(withIdentifier: "MyViewController") as? MyViewController
In this example:
vc1
is initialized with a custom title "Hello, World!".vc2
is initialized with the default title "Default Title".vc3
is instantiated from a storyboard, using the required initializer.
Example with Cells
UITableViewCell Initializers
Designated Initializers:
init(style:reuseIdentifier:)
: This is the designated initializer forUITableViewCell
. It's called when you initialize a cell programmatically.
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Custom initialization code here
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Custom initialization code here for cells created from a storyboard or nib
}
}
Convenience Initializers:
- Convenience initializers are not common for cells but can be added if you have specific configurations or default setups.
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Custom initialization code here
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Custom initialization code here for cells created from a storyboard or nib
}
convenience init() {
self.init(style: .default, reuseIdentifier: "CustomCell")
// Additional setup with default values
}
}
UICollectionViewCell Initializers
Designated Initializers:
init(frame:)
: This is the designated initializer forUICollectionViewCell
. It's called when you initialize a cell programmatically.
class CustomCollectionViewCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
// Custom initialization code here
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Custom initialization code here for cells created from a storyboard or nib
}
}
Convenience Initializers:
- Similar to
UITableViewCell
, you can create convenience initializers forUICollectionViewCell
for specific configurations.
class CustomCollectionViewCell: UICollectionViewCell {
override init(frame: CGRect) {
super.init(frame: frame)
// Custom initialization code here
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Custom initialization code here for cells created from a storyboard or nib
}
convenience init(withColor color: UIColor) {
self.init(frame: .zero)
self.backgroundColor = color
// Additional setup with the given color
}
}
Initializers for Storyboards and Nibs
When you use storyboards or nib files to create your custom cells, the system uses the init(coder:)
initializer. Here’s how you might set that up:
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// Custom initialization code here
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Custom initialization code here for cells created from a storyboard or nib
}
}
Summary
- Designated Initializers: Main initializers that ensure all properties are initialized and call the superclass initializer.
- Convenience Initializers: Secondary initializers that provide additional ways to initialize a class, calling another initializer within the same class.
- Required Initializers: Enforced initializers that must be implemented by subclasses, often used in protocol conformance.
These different types of initializers provide flexibility and clarity in how instances of a class are created and ensure that initialization is performed correctly and efficiently across the class hierarchy.