根据来自服务器和本地的数据集更新 TableView

Posted

技术标签:

【中文标题】根据来自服务器和本地的数据集更新 TableView【英文标题】:Update TableView based on dataset from server and local 【发布时间】:2021-10-02 19:32:10 【问题描述】:

我有一个显示所有新闻的 tableView,然后如果有任何新闻得到更新或添加了新新闻,我将按如下方式检查和更新。我想知道我的方法是否正确,并且还在寻找更好的选择(tableviewdiffsource?)

当前用户按顺序看到以下 4 条新闻

[n1, n2, n3, n4]

当用户拉动刷新时,他从服务器获得 3 条消息:[n4, n5, n6]

现在我应该按照 [n4, n5, n6, n1, n2, n3] 的顺序显示新闻

var allNews = [News]()
func didFetchNews(newNews:[News]) 
    var news:[News] = newNews
    var newsSet = Set(newNews)

    var deletedPaths = [IndexPath]()

    for i in 0..<allNews.count 
       let news = allNews[i];
       if !newsSet.contains(news) 
         news.append(news)
        else 
         deletedPaths.append(IndexPath(row: i, section: 0))
       
    

    var insertedPath = [IndexPath]()
    for i in 0..<newNews.count 
        insertedPath.append(IndexPath(row: i, section: 0))
    

    self.tableView.beginUpdates()
    self.tableView.insertRows(at: insertedPath, with: .automatic)
    self.tableView.deleteRows(at: deletedPaths, with: .automatic)
    self.tableView.endUpdates()

【问题讨论】:

【参考方案1】:

DiffableDataSource 可能是最有效的解决方案。

不过,您的代码也可以通过使用更高级别的函数来优化,例如 filtermap

首先计算更新新闻的索引。 由于新项目插入到顶部,因此插入索引路径等于新项目的索引。

然后在过滤后的索引处删除项目,并在索引 0 处插入新项目。reversed() 避免了超出范围的崩溃。

func didFetchNews(newNews: [News]) 
    let deletionIndices = allNews.indices.filternewNews.contains(allNews[$0])
    let deletionIndexPaths = deletionIndices.mapIndexPath(row: $0, section: 0)
    let insertionIndexPaths = newNews.indices.mapIndexPath(row: $0, section: 0)
    
    for index in deletionIndices.reversed()  allNews.remove(at: index) 
    allNews.insert(contentsOf: newNews, at: 0)

    self.tableView.beginUpdates()
    self.tableView.insertRows(at: insertionIndexPaths, with: .automatic)
    self.tableView.deleteRows(at: deletionIndexPaths, with: .automatic)
    self.tableView.endUpdates()
 

【讨论】:

非常感谢您提供这么漂亮的代码。我想知道我们先insertRows 然后deleteRows,而不是先deleteRows 然后insertRows。引用self.table.insertRows(at: IndexPaths),然后引用self.table.deleteRows(at: IndexPaths) 通过将insert/delete/move 语句包装在begin-/endUpdates 中,框架足够智能,可以按正确的顺序执行更改。 insertRowsdeleteRowsbegin endUpdates 中的排序无关紧要,对吧? 是的,block 内的顺序无关紧要。 非常感谢@vadian

以上是关于根据来自服务器和本地的数据集更新 TableView的主要内容,如果未能解决你的问题,请参考以下文章

Pentaho Kettle - 如何根据结果集生成更新查询?

使用来自另一个数据集的值搜索和更新 Spark 数据集列

根据更新的数据集自动重新训练分类模型

使用本地 SSAS 作为数据集的带有服务主体的嵌入式 powerbi 报告

R根据来自另一个数据集的间隔填充新列(查找)

如何准备 imagenet 数据集以运行 resnet50(来自官方 Tensorflow 模型花园)培训