[Swift] convenienceイニシャライザとdesignated(指定)イニシャライザ

  • 87
    Like
  • 0
    Comment
More than 1 year has passed since last update.

iBooksのSwift本を読んでいて、convenience initializerというのを見つけました。
また対比として、designated initializerという単語が出てきます。
要は指定イニシャライザです。

ちょっと文章とか曖昧なので、違ったら突っ込んでもらいたいんですが、convenience initializerは他のイニシャライザに処理を委譲(delegate)することができます。
つまりイニシャライザの中で別のイニシャライザを呼ぶことが出来ます。

sample.swift
class SomeClass {
    var name: String
    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "default name")
    }
}

var aClass: SomeClass = SomeClass() // => "name: default name"

convenienceの名前通り、デフォルトの処理があって、基本はそれに任せつつ、必要があれば引数を取って特別に処理をする、みたいなことを想定しているのでしょうか。

Super classを含めたイニシャライザ

上の例だけならなるほど、で終わりだったんですが、継承を含めるとさらに複雑になります。
サブクラスのイニシャライザ内で、Super classで定義された変数にアクセスする場合は、まず最初にsuper.initを呼ばないとなりません。(Super classのイニシャライザを呼んでからならアクセスできる)

さらにこのsuper.initを呼ぶ際、designated initializerを呼び出す必要があります。
(つまり、convenience initializerは呼べない)

ok.swift
class SubClass: SomeClass2 {
    var hoge: String
    init() {
        self.hoge = "foo" // Sub classで定義されている変数には`super.init`前にアクセス可能
        super.init(name: "hogehoge") // Super classのdesignated initializerは`init(name:)`
        self.name = "name" // Super classのinitializerを呼んだ後ならアクセスできる
    }
}
ng.swift
class SubClass: SomeClass2 {
    init() {
        self.name = "name" // `super.init`前に、Super classの変数にはアクセスできない
        super.init() // `convenience initializer`はSub classから直接呼べない
    }
}