Ios Swift中UITableView的动态数据源交换

Ios Swift中UITableView的动态数据源交换,ios,swift,uitableview,Ios,Swift,Uitableview,我是iOS/Swift开发新手,在为UITableView动态交换数据源时遇到问题-注意,我不是在交换代理,只是在交换数据源 我已经阅读了关于堆栈溢出的其他类似问题/回答,但没有找到与我的情况相关的问题/回答。通常,它们是关于将数据源设置为“viewDidLoad”(例如和),而我的情况是当用户按下按钮时交换数据源。我的代码中不存在引用问题中的问题 下面是我的代码概要。我将buttonPress方法连接到故事板中的TouchUpInside事件: class ViewController: UI

我是iOS/Swift开发新手,在为UITableView动态交换数据源时遇到问题-注意,我不是在交换代理,只是在交换数据源

我已经阅读了关于堆栈溢出的其他类似问题/回答,但没有找到与我的情况相关的问题/回答。通常,它们是关于将数据源设置为“viewDidLoad”(例如和),而我的情况是当用户按下按钮时交换数据源。我的代码中不存在引用问题中的问题

下面是我的代码概要。我将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中(没有错误-只是没有数据)。有什么想法吗?谢谢。

UITableView
数据源
属性是
不安全的
弱的
。无论哪种方式,与任何其他委托一样,它都不会保留强引用

所以当你写一行这样的话:

self.tableView.dataSource = DummyDataSource()
新实例化的
DummyDataSource()
属性没有任何指向它的强引用。因此,电弧会立即释放

如果我们想让数据源继续存在,我们需要保持对数据源的强引用

我的建议是向视图控制器添加一个数据源属性,该属性可以保留强引用。我们还将使用此属性的
didSet
设置表视图的数据源属性并重新加载其数据

var dataSource: UITableViewDataSource? {
    didSet {
        tableView?.dataSource = dataSource
        tableView?.reloadData()
    }
}
我们使用可选链接来防止在加载视图和填充
tableView
属性之前设置数据源。否则,尝试展开
nil
将出现致命错误


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

使用调试器。正在调用
DummyDataSource
的数据源方法吗?您不能只初始化并分配数据源类。创建一个实例,然后赋值。@rmaddy-我刚刚在DummyDataSource中的count和new cell方法中添加了一个打印,我看到count方法确实被调用了。@NickHarris我的回答解释了这一切。如果有任何需要进一步澄清的地方,只需在答案上留下评论。欢迎光临,你的问题终于解决了。下面的@nhgrif解释了这一点。事实上,在较新的iOS版本中,
很弱。你知道这是什么时候改变的吗?因为iOS 9:。谢谢。我已经把这个链接添加到了答案中。在少数情况下,代理引用很强。您可能希望将答案改为“与几乎所有代表一样…”