【问题标题】:UITableViewController datasource not reading new valuesUITableViewController 数据源未读取新值
【发布时间】:2019-08-01 07:15:31
【问题描述】:

我有以下模型、基本 UITableViewController 类和 UITableViewController 的子类:

型号

class Product {

    var title: String
    var prices: [Int]

}

UITableViewController - 超类

class BaseTableController: UITableviewController {

    var items: [Product] = [Product]()

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchData()
    }

    // MARK: - UITableViewDataSource

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

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
        let item = items[indexPath.item]
        Logger.debug("FOUND \(item.prices.count) PRICES")
        return cell
    }

    // MARK: - Data

    func fetchData() {
        let dispatchGroup = DispatchGroup()

        items.forEach { (item) in
            dispatchGroup.enter()
            APIService.shared.getPrices(product: item) { (prices) in
                item.prices = prices
                dispatchGroup.leave()
            }
        }

        dispatchGroup.notify(queue: DispatchQueue.main) {
            self.tableView.reloadData()
        }
    }

}

UITableViewController - 子类

class MyFancyTable: BaseTableController {

    override var items: [Product] {
        set {}
        get {
            return [
                Product(title: "FOOD"),
                Product(title: "DRINK")
            ]
        }
    }

}

我将使用 MyFancyTable 从不同的产品类别中获取价格。

当 API 返回响应时,它将更新 items 变量中的价格,然后我重新加载表格。

但是,当我在子类 (MyFancyTable) 中覆盖 items 时,即使在 API 回调期间价格已更新,记录器(在 cellForRowAtIndexPath 中)仍会读取零价格。好像从来没有更新过一样。

日志结果:

FOUND 0 PRICES - 食品

FOUND 0 PRICES - 饮料

我可以确认 API 返回多个价格。

我们将不胜感激。谢谢!

【问题讨论】:

  • 你永远不会进入 DispatchGroup。
  • 我看不出你是怎么拉东西的。
  • 很抱歉我删除了很多代码以使其更具可读性(代码部分已更新)。
  • 您是否设置了断点以确保调用reloadData()
  • @Xcoder,是的...我可以确认调用了reloadData()。然后它再次转到cellForRowAtIndexPath,打印出两种产品的 0 个价格。

标签: swift uitableview datasource subclass


【解决方案1】:

您的问题可能导致您将 items 变量设置为计算属性,这意味着每次调用它都会重新计算它

试试这个:

class MyFancyTable: BaseTableController {

     override var items: [Product] = [Product(title: "FOOD"),Product(title: "DRINK")]
}

【讨论】:

  • 当我试图以这种方式覆盖它时,xcode 给了我这个错误:Cannot override with a stored property 'items'
  • 嗯,我认为你应该改变你的概念,在BaseTableController中你可以设置你的UI,例如tableView,在它的子类中你实现fetchData并声明items属性
  • 谢谢,我已经根据您的建议发布了解决方案。 ?
【解决方案2】:

我终于想出了一个解决办法(根据 Tung Vu Duc 的建议)。基本上我需要在子类的init 函数中覆盖items,而不是像我最初那样通过计算属性来实现。

子类现在看起来像:

class MyFancyTable: BaseTableController {

    required init?(coder aDecoder: NSCoder) {
        fatalError()
    }

    init() {
        super.init(nibName: nil, bundle: nil)

        items = [
            Product(title: "FOOD"),
            Product(title: "DRINK")
        ]
    }

}

谢谢大家!

【讨论】:

    猜你喜欢
    • 2016-03-03
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 2014-03-12
    • 1970-01-01
    • 2020-11-10
    相关资源
    最近更新 更多