UITableViewを軽量化する！(Swift版）

# 概要
UITableViewのUITableViewDataSourceを分離し、UIViewControllerを軽くする方法を共有します。

[Obj-C版はこちら](http://qiita.com/eKushida/items/9613e3af0491581b5dc5)

下記のサイトを参考にさせて頂きました。
[Objc.io](https://www.objc.io/issues/1-view-controllers/lighter-view-controllers/)

#### *やること*
・UITableViewDataSourceをUIViewContorlllerから分離する

#### *やらないこと*
・UITableViewCellのレイアウトについて
・UITableViewDelegateの分離について

# 実装手順
今回は、テキストを表示するだけのシンプルなTableViewでご説明します。

1. TableViewに表示するデータを管理するクラスを作る
2. UITableViewDataSouceの拡張クラスを作る
3. UITableViewCellの拡張したクラスを作る
4. UIViewControllerから呼び出す

## 1. TableViewに表示するデータを管理するクラスを作る

```:Item.swift
import UIKit

class Item: NSObject {
    var title = ""
    
    init(title: String) {
        self.title = title
    }
}

```

## 2. UITableViewDataSouceの拡張クラスを作る

```ItemDataSource.swift
import  UIKit

typealias TableViewCellConfigureBlock = (cell: UITableViewCell, item: NSObject) -> Void

class ItemDataSource: NSObject {
    
    var items = [NSObject]()
    var cellIdentifier = ""
    var configureCellBlock: TableViewCellConfigureBlock?
    
    init(items: [Item], cellIdentifier: String, configureCellBlock: TableViewCellConfigureBlock) {
        self.items = items
        self.cellIdentifier = cellIdentifier
        self.configureCellBlock = configureCellBlock
    }
}

extension ItemDataSource: UITableViewDataSource {

    //MARK: - UITableViewDataSource
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell =  tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier,
                                                                forIndexPath: indexPath)
        
        if let configureCellBlock = self.configureCellBlock {
            configureCellBlock(cell: cell, item: self.itemAtIndexPath(indexPath))
        }
        
        return cell
    }
    
    //MARK: - Private
    private func itemAtIndexPath(indexPath: NSIndexPath) -> NSObject{
        return items[indexPath.row]
    }
}
```

## 3. UITableViewCellの拡張したクラスを作る

```ItemCell.swift
import UIKit

class ItemCell: UITableViewCell {
    
    @IBOutlet weak var titleLabel: UILabel!
    
    var item: Item? {
        didSet {
            
            if let item = item {
                self.titleLabel.text = item.title                
            }
        }
    }
}
```

## 4. UIViewControllerから呼び出す
今回作ったItemDataSourceのインスタンスをUITableViewのdataSourceプロパティにセットするだけです。

```:ViewController.swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var dataSource: ItemDataSource?
    
    //MARK: - LifeCycle
    override func viewDidLoad() {
        super.viewDidLoad()
        self.setup()
    }

    //MARK: - Private
    private func setup() {
        
        dataSource = ItemDataSource(items: [Item(title: "株式会社"),Item(title: "スマートデバイス"),Item(title: "テクノロジー")],
                         cellIdentifier: "ItemCell") { (cell, item) in
            if let cell = cell as? ItemCell, let item = item as? Item {
                cell.item = item
            }
        }
        tableView.dataSource = dataSource
    }
}

```

# 完成イメージ

<img width="133" alt="スクリーンショット 2015-12-02 22.56.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/71694/4b3ad814-91ae-4d68-9a13-38296b8341fc.png">

# まとめ
UITableViewDataSourceを分離でき、UIViewControllerの肥大化を防げました。

誤りや、もっとよい方法がございましたら、ご指摘頂ければ幸いです。