Swift中UITableView的动态DataSource交换

nic*_*ris 2 uitableview ios swift

我是iOS/Swift开发的新手,并且在为UITableView进行DataSource的动态交换时遇到问题 - 请注意,我没有交换Delegate,只是数据源.

我已经在Stack Overflow上阅读了其他类似的问题/回复,但没有找到与我的情况相关的问题.通常他们是关于在"viewDidLoad"上设置DataSource(例如这一个,这个),而我的情况是关于当用户按下按钮时交换DataSource.我的代码中不存在引用问题中的问题.

这是我的代码大纲.我将buttonPress方法连接到storyboard中的TouchUpInside事件:

class ViewController: UIViewController, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    ...    

    @IBAction func buttonPress(sender: UIButton) {

        ...

        self.tableView.dataSource = DummyDataSource()
        self.tableView.delegate = self
        self.tableView.reloadData()

    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

......这是我的数据源类:

import UIKit

class DummyDataSource: NSObject, UITableViewDataSource {

    let names = ["A", "B", "C"]

    func tableView(tableView: UITableView,
                     numberOfRowsInSection section: Int) -> Int {
        return names.count
    }

    func tableView(tableView: UITableView,
                     cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier(simpleTableIdentifier) as UITableViewCell?

        if ( cell == nil ) {
            cell = UITableViewCell( style: UITableViewCellStyle.Default,
                                reuseIdentifier: simpleTableIdentifier)
        }

        cell!.textLabel?.text = names[indexPath.row]
        return cell!

    }

}
Run Code Online (Sandbox Code Playgroud)

当我按下按钮时,我可以看到正确调用了pressButton方法,但是数据没有显示在tableView中(没有错误 - 只是没有数据).有什么想法吗?谢谢.

nhg*_*rif 5

UITableViewdataSource属性是unsafe_unretained或者weak,取决于iOS的版本.无论哪种方式,与任何其他代表一样,它没有强有力的参考.

所以当你写这样一行时:

self.tableView.dataSource = DummyDataSource()
Run Code Online (Sandbox Code Playgroud)

您新实例化的DummyDataSource()属性没有指向它的任何强引用.因此,它立即被ARC发布.

如果我们希望它能够坚持下去,我们需要对数据源保持强有力的参考.

我的建议是向视图控制器添加一个数据源属性,以保持强引用.我们还将使用didSetthis属性来设置表视图的数据源属性并重新加载其数据.

var dataSource: UITableViewDataSource? {
    didSet {
        tableView?.dataSource = dataSource
        tableView?.reloadData()
    }
}
Run Code Online (Sandbox Code Playgroud)

我们使用optional-chaining来防止在加载视图和tableView填充属性之前设置的数据源.否则,我们将尝试打开时出现致命错误nil.

我们不需要在其他任何地方的表视图上设置数据源属性.我们需要reloadData()在其他任何地方调用的唯一原因是我们的数据源本身是否可以更改它所代表的数据.但是,重要的reloadData()是与重置同步调用dataSource以防止一些可能的索引越界崩溃.

  • 实际上,它在较新的 iOS 版本中是“弱”的。 (2认同)