kitoko552.memo

kitoko552のメモ

lazyを使って他のプロパティを使うプロパティの初期化を宣言時に実現する

要点

  • lazy を使えば他のプロパティを必要とするプロパティの初期化を宣言時にすることができる。
  • その場合は型宣言を書かなければエラーが出るので注意する。
  • 他のプロパティにはselfを書かないとエラーが出る。
private lazy var hakuba: Hakuba = Hakuba(tableView: self.tableView)

ViewControllerでのプロパティの初期化が煩わしい

ViewControllerでプロパティを宣言・初期化するとき、特に他のプロパティを使って初期化する場合は、宣言時に初期化できない場合はOptional型にしなければいけないので以下のようなことが起きます。

class ViewController: UIViewController {
    @IBOutlet var tableView: UITableView!
    private var hakuba: Hakuba?

    override func viewDidLoad() {
        super.viewDidLoad()
        hakuba = Hakuba(tableView: tableView)
    }

    private func doSomething() {
        guard let hakuba = hakuba else {
            return
        }

        // use hakuba
    }
}

doSomething()内でguardでプロパティがnilでないことを確認した上でそのプロパティを使わなければなりません。
このクラスのメソッドがdoSomething()だけならまだしも、他のメソッドでもプロパティを使う場合はメソッドごとにguardを使わなければいけません。
これは非常に面倒です。

この場合は宣言時に!でimplicitly unwrapped optionalにしてしまえばいいんですが、Swiftエンジニアとしてはあまり使いたくありません。

class ViewController: UIViewController {
    @IBOutlet var tableView: UITableView!
    private var hakuba: Hakuba!

    override func viewDidLoad() {
        super.viewDidLoad()
        hakuba = Hakuba(tableView: tableView)
    }

    private func doSomething() {
        // use hakuba
    }
}

lazyを使って宣言時に初期化する

これを解決する方法として、lazyを使う方法があります。
lazyを使えばプロパティ宣言時に初期化できるため、プロパティをオプショナル型にする必要がなくなります。

class ViewController: UIViewController {
    @IBOutlet var tableView: UITableView!
    private lazy var hakuba: Hakuba = Hakuba(tableView: self.tableView)

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    private func doSomething() {
        // use hakuba
    }
}

いいね!!

注意点

しかし注意点が2点あります。
lazyを使ってプロパティを初期化する際は 型宣言を書かなければいけない という点と、他のプロパティにはselfをつけなければいけない ということです。

できるだけ省略して上のようなプロパティの初期化をやろうと思うと以下のように書いてしまうと思います。

private lazy var hakuba = Hakuba(tableView: tableView)

しかしこれだとエラーが出てしまいビルドできません。

型宣言を書き、

private lazy var hakuba: Hakuba = Hakuba(tableView: tableView)

他のプロパティにはselfをつけましょう。

private lazy var hakuba: Hakuba = Hakuba(tableView: self.tableView)