Ios UITableViewDiffableDataSouce:更新无效:节数无效

Ios UITableViewDiffableDataSouce:更新无效:节数无效,ios,swift,uitableview,uitableviewdiffabledatasource,Ios,Swift,Uitableview,Uitableviewdiffabledatasource,我正在尝试应用空快照,它正在使我的应用程序崩溃。我已经试着调试它两天了,但似乎找不到解决这个问题的方法。下面是我正在运行的代码: // // ItemsListDiffableVC.swift // FetchRewardsCodingExercise // // Created by Vandan Patel on 11/26/20. // import UIKit final class ItemsListDiffableVC: UIViewController { pri

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

//
//  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?
}
我不明白的是为什么在更新之前还有一个部分,以及如何处理它


谢谢。

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


这毫无意义:

    var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
    dataSource.apply(snapshot, animatingDifferences: true, completion: nil)
您不需要使用单独的实例变量来保存可扩散数据源中的数据。可扩散数据源本身保存数据,在应用数据时,快照会将数据传递给它


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

首先,UIDiffableDataSource不是为引用类型创建的,因此,我建议您将所有模型类转换为结构。

我遇到了相同的问题,我所做的是将
动画差异设置为false,崩溃消失了

什么是项目?你的数据在哪里?应用空快照的目的是什么?请展示你的真实代码,并解释你的真实目标。另外,
[Dictionary.Element]
是一种奇怪的说话方式。我只是想帮助你找出应用程序崩溃的原因。我应用了一个空快照,这样我们可以很容易地看到一个错误。尽管我应用了一个空快照,但错误显示它在更新之前有1个部分。这就是我想弄明白的。1.为什么我一初始化tableView就变成了1节?2.如果是1,如何使其为0?谢谢您没有提供足够的代码来测试这个问题。请提供一个执行崩溃的工作的、可编译的、自包含的示例。您的代码仍然无法编译。什么是项目列表?什么是项目单元?什么是可查看的项目?
sectionTitle
属性来自哪里?如果我不能编译它,我就不能运行它,如果我不能运行它,我就不能崩溃。我正在应用一个空快照,以使调试更容易。不合理的是,为什么应用空快照时它会崩溃。这个崩溃是特定于部分的,我已经分享了所有相关的代码。然而,我不介意分享更多。我注意到tableView在初始化时有1个部分,这使得它以1的速度关闭,从而导致崩溃。感谢您抽出时间回复。这不准确。“只要类型是可散列的,就可以了。”Drew起初我也这么认为。但在一个演示项目中,我遇到了问题,我把这个错误提交给了苹果反馈助手,看看他们的回复。所以我很震惊,所以我决定进一步调查,我检查了苹果提供的所有可扩散数据源演示,发现他们的示例都没有使用引用类型。@CrackIt这很有趣,因为文档中没有提到这一要求。我还能够使用类来获得可扩散的数据源。这很有趣,因为文档中没有提到这个要求。我还能够通过使用类来获得可扩散的数据源。耶@Drew。所以我现在完全糊涂了。通常我现在避免使用引用类型。虽然在最近的WWDC 21中有一些新的变化,但是你应该去看看。我们可能用错了整个可扩散数据源的方法!
    var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
    dataSource.apply(snapshot, animatingDifferences: true, completion: nil)
class ItemDataSource: UITableViewDiffableDataSource<Section, Item> {
    var groupedItems = [Dictionary<Int, [Item]>.Element]()
}