我是iOS / Swift开发的新手,并且在为UITableView进行DataSource的动态交换时遇到问题 - 请注意,我没有交换Delegate,只是数据源。
我已经在Stack Overflow上阅读了其他类似的问题/回复,但找不到与我的情况相关的问题/答案。通常它们是关于在“viewDidLoad”(例如this one和this one)上设置DataSource,而我的情况是关于当用户按下按钮时交换DataSource。我的代码中不存在引用问题中的问题。
这是我的代码大纲。我将buttonPress方法连接到故事板中的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()
}
...
}
...这是我的数据源类:
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!
}
}
当我按下按钮时,我可以看到正确调用了pressButton方法,但数据没有显示在tableView中(没有错误 - 只是没有数据)。有什么想法吗?谢谢。
答案 0 :(得分:5)
UITableView
dataSource
属性为unsafe_unretained
或weak
,depending on which version of iOS。无论哪种方式,与任何其他代表一样,它也没有强有力的参考。
所以当你写这样的一行时:
self.tableView.dataSource = DummyDataSource()
您新实例化的DummyDataSource()
媒体资源没有指向它的任何强引用。因此,它立即由ARC发布。
如果我们希望它能够坚持下去,我们需要对数据源保持强有力的参考。
我的建议是将数据源属性添加到视图控制器,这可以保留强引用。我们还将使用此属性的didSet
来设置表格视图的数据源属性并重新加载其数据。
var dataSource: UITableViewDataSource? {
didSet {
tableView?.dataSource = dataSource
tableView?.reloadData()
}
}
我们使用optional-chaining来防止在加载视图之前设置的数据源并填充tableView
属性。否则,我们将尝试解开nil
时出现致命错误。
我们不需要在其他任何地方的表视图上设置数据源属性。我们需要在其他任何地方调用reloadData()
的唯一原因是我们的数据源本身是否可以更改它所代表的数据。但是,重要的是reloadData()
与重置dataSource
同步调用,以防止某些可能的索引跳出崩溃。