遅延生成で生成時に色々設定を入れる方法

`View` や `ViewController` を作る際に、初期化にあまり時間をかけたくないなどといった理由ですぐに使わないけど Optional でない部品を `lazy var` 使って遅延生成する手法があります。例えば `ViewController` に `ChildViewController` を持ちたいけど、実際 `ChildViewController` が必要になるまで生成したくないといった場合がまさにこうです。

```swift:ViewController
import UIKit

class ViewController: UIViewController {
	
	lazy var childController = ChildViewController()
	
	override func viewDidLoad() {
		super.viewDidLoad()
		// Do any additional setup after loading the view, typically from a nib.
		print("Root controller view did load")
	}
	
	override func didReceiveMemoryWarning() {
		super.didReceiveMemoryWarning()
		// Dispose of any resources that can be recreated.
	}
	
	override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
		print("Touches in root controller ended")
		self.presentViewController(self.childController, animated: true) {
			print("Child controller presented")
		}
	}
	
}
```

```swift:ChildViewController
import UIKit

class ChildViewController: UIViewController {
	
	init() {
		super.init(nibName: nil, bundle: nil)
		print("Child controller inited")
	}
	
	required init?(coder aDecoder: NSCoder) {
		fatalError("init(coder:) has not been implemented")
	}

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
		print("Child controller view did load")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
	
}
```

この場合、`ViewController` にタップするまで、`ChildViewController` の部品は生成されないことをログで見れば一目瞭然です。

```text
Root controller view did load
Touches in root controller ended
Child controller inited
Child controller view did load
Child controller presented
```

ところが、このような単純な `lazy var` を使う場合、生成時に色々設定を入れてあげること（`backgroundColor` を設定してあげたいとか色々）ができません。

じゃあどうすればいいかというと、少なくとも二通りの方法があります。

まず一つ目は非常にレガシーなやり方で Objective-C の時代からある方法です。もう一つ `private` 変数を使うことです。例えば上記の `lazy var childController = ChildViewController()` ですと、下記のように書きます：

```swift:ViewController
//前略
	private var _childController: ChildViewController?
	var childController: ChildViewController {
		if let controller = self._childController {
			return controller
			
		} else {
			let controller = ChildViewController()
			self._childController = controller
			controller.view.backgroundColor = .redColor()
			return controller
		}
	}
//後略
```

このように、一つ `private var _childController` という変数を作ることによって、`lazy var` と同じ効果が得られる上、生成時に色々設定をしてあげることも可能です。

もう一つの方法は `lazy var` をそのまま使うが、クロージャーも一緒に取り入れるという Swift ならではの方法です：

```swift:ViewController
//前略
	lazy var childController = {() -> ChildViewController in
		let controller = ChildViewController()
		controller.view.backgroundColor = .redColor()
		return controller
	}()
//後略
```

両方とも通常の `lazy var` の時と全く同じように `self.childController` でそのまま使えますが、クロージャーの方が余計なインスタンス変数を作らずに済むし記述量も少ないのでとてもスマートなコードが書けます。~~ただし一つだけ制限もありまして、`lazy var` を使う場合は使われてる時クラスが生成されたことが保証できないため、クロージャーの中に `self` が使えません。なので `self` を使った設定は `private var _`を使うしかなさそうです。~~コメント情報によりますと、クロージャーの中に `self` を使いたい場合は型を明示すればできます：

```swift:ViewController
//前略
	lazy var childController: ChildViewController = {
		let controller = ChildViewController()
		controller.view.backgroundColor = self.view.backgroundColor()
		return controller
	}()
//後略
```