UIVIewController.viewの生成タイミング

Instantiateというライブラリがあります。

github.com

StoryboardやXibを使いつつコンストラクタインジェクションできる素敵ライブラリなのですが、コードを読んでてよくわからなかったところがありました。

Instantiate/Storyboard+UIViewController.swift at master · tarunon/Instantiate · GitHub

このコードの self.view を参照しているところ。 左辺が _ となっているので何もしてないように見えます。

            if self is ViewLoadBeforeInject {
                _ = self.view
            }

ViewLoadBeforeInject というのはプロトコルで、定義はこんな感じ。

/// This protocol allow viewController force load view before call `inject`
public protocol ViewLoadBeforeInject {
    
}

コメントを読むと、 UIViewController.viewinject が呼ばれる前に強制的にロードするもののようです。

inject はコンストラクタ内で呼ばれるメソッドです。

色々読んでるうちに UIViewContoroller.view のコメントにたどり着き理解できました。

    open var view: UIView! // The getter first invokes [self loadView] if the view hasn't been set yet. Subclasses must call super if they override the setter or getter.

先程のコードはコンストラクタ中のコードであり、最初のアクセスなのでviewを生成してるようです。

ゲッターにこんな副作用持たせてるとは思わなかった。

このコードのおかげで、inject メソッドで UIViewContoroller に置いてある UILabel とかをセットするような場合に、このプロトコルを適用すればクラッシュしません。

内部の変数に保持して ViewDidLoad とかでセットするなら、このプロトコルは不要です。

うまいことできてる。