-1

我正在尝试应用一个空快照,它使我的应用程序崩溃。我已经尝试调试它 2 天了,但似乎无法找到解决此问题的方法。下面是我正在运行的代码:

//
//  ItemsListDiffableVC.swift
//  FetchRewardsCodingExercise
//
//  Created by Vandan Patel on 11/26/20.
//

import UIKit

final class ItemsListDiffableVC: UIViewController {
    private var tableView: UITableView!
    private var dataSource: ItemDataSource!
    private var groupedItems = [Dictionary<Int, [Item]>.Element]()
    
    var presenter: ItemsListPresentable!
    
    private let cellReusableID = "itemCell"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureTableView()
        presenter.didLoadView()
    }
    
    private func configureTableView() {
        tableView = UITableView()
        tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        tableView.backgroundColor = .systemGroupedBackground
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReusableID)
        view.addSubview(tableView)
    }
    
    private func configureDataSource() {
        dataSource = ItemDataSource(tableView: self.tableView, cellProvider: { (tableView, indexPath, item) -> UITableViewCell? in
            let cell = tableView.dequeueReusableCell(withIdentifier: self.cellReusableID, for: indexPath) as! ItemCell
            cell.configureCell(withTitle: item.name ?? "")
            return cell
        })
    }
}

extension ItemsListDiffableVC: ItemsListViewable {
    func display(groupedItems: [Dictionary<Int, [Item]>.Element]) {
        DispatchQueue.main.async {
            self.configureDataSource()
            self.update(with: groupedItems)
        }
    }
    
    func display(error: String) {
    }
}

extension ItemsListDiffableVC {
    private func update(with groupedItems: [Dictionary<Int, [Item]>.Element]) {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
        dataSource.apply(snapshot, animatingDifferences: true, completion: nil)
    }
}

class Section: Hashable {
    
    let sectionName: String
    let identifier = UUID()
    
    init(sectionName: String) {
        self.sectionName = sectionName
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(identifier)
    }
    
    static func == (lhs: Section, rhs: Section) -> Bool {
        return lhs.identifier == rhs.identifier
    }
}

class ItemDataSource: UITableViewDiffableDataSource<Section, Item> {
    var groupedItems = [Dictionary<Int, [Item]>.Element]()
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return groupedItems[section].key.sectionTitle
    }
}

struct Item: Codable, Hashable {
    let id: Int
    let listId: Int
    let name: String?
}

这是我得到的错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (0) must be equal to the number of sections contained in the table view before the update (1), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'

我不明白的是为什么在更新之前还有一个部分以及如何处理它。

谢谢。

4

4 回答 4

1

我遇到了同样的问题,我所做的是变成animatingDifferences了假并且崩溃消失了

于 2021-05-28T19:04:41.080 回答
0
tableView.dataSource = dataSource

我在呈现的代码中的任何地方都看不到这一点。

于 2021-07-25T00:29:38.357 回答
0

我怀疑问题在于您没有向我们展示的代码(因为代码显然不完整;您没有声明 Item,而且您似乎在任何地方都没有任何数据)。但是,这里有一些关于您展示的代码的想法:


这没有任何意义:

    var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
    dataSource.apply(snapshot, animatingDifferences: true, completion: nil)

那个快照是的。因此,没有要更新的数据,也没有要应用的差异。您的函数已命名 func update(with groupedItems:,但实际上无论groupedItems传递给您什么,您都只是将它们扔掉并使用这个空快照。


此外,在最初填充数据源后(仅发生一次),您永远不会再次创建快照。您始终从数据源获取每个后续​​快照,对其进行修改并应用它。


此外,这显示了对什么是 diffable 数据源的误解:

class ItemDataSource: UITableViewDiffableDataSource<Section, Item> {
    var groupedItems = [Dictionary<Int, [Item]>.Element]()
}

您不使用单独的实例变量将数据保存在可区分的数据源中。diffable 数据源本身持有数据,这些数据在应用时由快照传递给它。

基本上,您需要确定这些数据的真实来源,并从那里一致地填充表格视图数据源。通常情况下,diffable 数据源本身就是事实的来源;如果您有充分的理由使用“后备存储”,那很好(也许您的数据会从网络异步更新自己?),但是不要使用其中的两个

于 2020-11-29T17:35:53.303 回答
0

首先,UIDiffableDataSource 不是为引用类型制作的,所以我建议请将您的所有模型类转换为结构。

于 2020-11-29T17:49:51.447 回答