しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

Swiftのプロパティーと初期化とConvenience initializer

init周りのConvenienceとかDesignatedとかのエラーが出たけどなんのことか分からなかったので調査。

基本的なinit

一番簡単なinitは下の通りです。
普通の関数と違ってfuncは不要です。
Objective-cself = [super init];if (self != nil) {}みたいな処理がないのが嬉しいですね。

class A {
    init() {
        // 処理
    }
}

引数付きのinitは下の通りです。
通常のメソッドと違って呼び出す際に第一引数名を省略できません。

class A {
    init(a: Int) {
        // 処理
    }
}
A(a: 1) // A(1)とは書けない

引数を省略したい場合は下のように_を付けます。

class A {
    init(_ a: Int) {
        // 処理
    }
}
A(1)

プロパティーと初期化とConvenience initializer

Swiftではimmutableなプロパティーがある場合、必ず宣言時かinitializerで値を入れる必要があります。

class A {
    let num: Int
    let str: String = ""
    init(a: Int) {
        num = 100 // これを書かないとエラー
    }
}

Initializerが増えた場合、全てに対してプロパティーの初期化をする必要があります。
self.init(a: 1)のように他のinitializerを呼び出す事はできない為、同じ値を入れる場合も毎回値を入れる必要があります。

class A {
    let num: Int
    let str: String = ""
    init(a: Int) {
        num = 100
    }
    init(s: String) {
        num = 100 // self.init(a: 1)はできない
    }
    init(d: Double) {
        num = 200
    }
}

そこで登場するのがConvenience initializerです。
Convenience initializerは他のinitializerを呼び出す事ができます。
先頭にconvenience修飾子をつければConvenience initializerになります。
なお、Convenience initializer以外のinitializerはDesignated initializerと呼ばれます。

class A {
    let num: Int
    let str: String = ""
    init(a: Int) {
        num = 100
    }
    convenience init(s: String) {
        self.init(a: 1) // 逆にnum = 100ができなくなる
    }
}

まとめ

swiftのInitializerは最初は難解だったのですが、全てはimmutableなプロパティーの複数回代入を防ぐためと分かり納得する事ができました。
この厳密さはObjective-cではなかった部分なので、勉強していて楽しいです。
しかしその分制約が多いので初心者からiPhoneアプリを作る場合に少し辛そうな印象を受けました。
個人的にはSwift大好きです。