Saturday, March 21, 2015

Overview

Initializers in Swift are a little different than the ones found in other classes. This post is all about the dreadful init. You can find more information on initialization here.

Content

There are 2 kinds of inits: designated init and convenience init.

1
2
3
4
5
6
7
class MyClass {
    var instanceVariable:Int

    init(passedVariable: Int){
        instanceVariable = passedVariable
    }
}

In an init, you must initialize all your properties. This includes constants (that use let) and optionals. Optionals can have a value of nil so they are initialized by default.

1
2
3
4
5
6
7
8
class MyClass {
    let constantVar:String
    var optionalVar:String?

    init(passedVar:String) {
        constantVar = passedVar
    }
}

Designated Init

A designated init must first initialize all of its own properties before calling super.init.

A designated init must call super.init before assigning a value to an inherited property.

Convenience Init

A convenience init must call a designated init of its own class (can’t call super.init).

1
2
3
4
5
6
7
8
9
class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "[Unnamed]")
    }
}

Results

A convenience init must call a designated init before it can set any property values.

A convenience init can call a designated init indirectly (through another convenience init)

1
2
3
4
5
6
7
8
9
10
class RecipeIngredient: Food {
    var quantity: Int
    init(name: String, quantity: Int) {
        self.quantity = quantity
        super.init(name: name)
    }
    override convenience init(name: String) {
        self.init(name: name, quantity: 1)
    }
}

Results

Inherited Init

If you inherit from a class and provide no inits. You inherit all the super class’ inits.

1
2
3
4
5
6
7
8
class ShoppingListItem: RecipeIngredient {
    var purchased = false
    var description: String {
        var output = "\(quantity) x \(name)"
        output += purchased ? " ✔" : " ✘"
        return output
    }
}

Results

Required Init

You can force a subclass to override a super class’ initializer by adding required in front.

1
2
3
4
5
6
7
8
9
10
11
12
class SomeClass {
    required init() {
        // initializer implementation goes here
    }
}

class SomeSubclass: SomeClass {
    //subclass also needs a 'required' keyword
    required init() {
        // subclass implementation of the required initializer goes here
    }
}

Failable Init

An initializer can fail and return nil. Why would we do this? Here’s one example.

1
2
3
4
5
6
7
let image = UIImage(named: "imageName") //image is an (UIImage?)

if let otherImage = UIImage(named: "imageName") {
    // image was successfully created
} else {
    // couldn't create the image
}

Random Posts