LoginSignup
51
50

More than 5 years have passed since last update.

swiftでDelegate/DataSourceを分離したいときに気をつけること

Posted at

UITableViewのDataSourceやDelegateを分離しようとしてうまくいかなかった話。

DelegateになるにはNSObjectを継承している必要がある

UIKitのDelegateはそれぞれNSObjectProtocol継承であるっぽい。
なので

class MyTableViewDataSource : NSObject, UITableViewDataSource{

}

といった具合で継承されてないとうまくいかない

Delegateはメンバ変数化しておく

これは完全にswiftから入ったがゆえかなあと思った。

例えばさくっとこんな感じで書いたとすると

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.dataSource = TableViewDataSource()
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    // DataSourceの件数そのまま出すといいだろうーみたいな感覚
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return  (self.tableView.dataSource as TableViewDataSource).data.count
    }
}

みたいなことをしているとEXC_BAD_ACCESSに見舞われる。
一体何なんだこれはと思っていたがおそらくdataSourceの参照先が開放されてしまっているのだろう。

なので下記のようにViewControllerのメンバーにしておく必要がある模様。

class TableViewController: UITableViewController {
    var dataSource : TableViewDataSource = TableViewDataSource()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.dataSource = dataSource
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataSource.data.count
    }
}
51
50
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
50