【问题标题】:Dynamic DataSource swap for UITableView in SwiftSwift 中 UITableView 的动态数据源交换
【发布时间】:2016-08-21 16:47:07
【问题描述】:

我是 iOS/Swift 开发的新手,在为 UITableView 进行 DataSource 的动态交换时遇到问题 - 请注意,我不是在交换 Delegate,只是交换 DataSource。

我已阅读有关 Stack Overflow 的其他类似问题/回复,但未找到与我的情况相关的问题。通常他们是关于在“viewDidLoad”上设置数据源(例如this onethis one),而我的情况是当用户按下按钮时交换数据源。我的代码中不存在引用问题中的问题。

这是我的代码大纲。我将 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 中(没有错误 - 只是没有数据)。请问有什么想法吗?谢谢。

【问题讨论】:

  • 使用调试器。你DummyDataSource的数据源方法被调用了吗?
  • 您不能只初始化和分配数据源类。创建一个实例,然后分配。
  • @rmaddy - 我只是在我的 DummyDataSource 中的 count 和新单元格方法中添加了一个 print,我看到 count 方法确实被调用了。
  • @nickpharris 我的回答说明了一切。如果需要进一步澄清,只需对答案发表评论即可。
  • 欢迎您,您的问题终于解决了。它由下面的@nhgrif 解释..就是这样

标签: ios swift uitableview


【解决方案1】:

UITableViewdataSource 属性是unsafe_unretainedweakdepending on which version of iOS。无论哪种方式,与任何其他委托一样,它都不会保留强引用。

所以当你这样写一行时:

self.tableView.dataSource = DummyDataSource()

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

如果我们希望数据源持续存在,我们需要保持对数据源的强引用。

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

var dataSource: UITableViewDataSource? {
    didSet {
        tableView?.dataSource = dataSource
        tableView?.reloadData()
    }
}

我们使用可选链来防止在加载视图和填充tableView 属性之前设置数据源。否则,我们将在尝试打开 nil 时遇到致命错误。

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

【讨论】:

  • 在较新的 iOS 版本中实际上是 weak
  • 你知道什么时候改变了吗?
  • 谢谢。我已将该链接添加到答案中。
  • 在极少数情况下,委托引用很强。您可能想将答案更改为“与几乎所有代表一样......”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多