gpt4 book ai didi

swift - 主线程和 Collectionview.reloadData()

转载 作者:行者123 更新时间:2023-12-05 03:47:10 26 4
gpt4 key购买 nike

我遇到这样一种情况,代码更改其 collectionView 数据源,然后多次调用 reloadData(),我认为这会导致我的应用程序因竞争条件而崩溃,因为数据源变化非常快,所以我用 DispatchQueue.main.async 包装了一段代码(更改数据源然后重新加载 Collection View )并且崩溃消失了。所以这个问题是否有意义并解决了竞争条件,我的理解是用 DispatchQueue.main.async 包装这段代码将不会再次执行此代码段,直到 reloadData() 函数完成,是对吗?如果您对如何解决此问题有任何其他想法,那就太好了

更新:

例如,如果我们在主线程

上有这段代码
self.collectionView.dataSource = self.dataSource
self.collectionView.reloadData()

这段代码快速地接连调用了两次,因此在第一次重新加载时数据源发生了变化,作为解决方案,我用async block 包装了这段代码,以确保在第一次重新加载完成之前数据源不会更改。像下面这样:

DispatchQueue.main.async {
self.collectionView.dataSource = self.dataSource
self.collectionView.reloadData()
}

这是否可以保证在 reloadData() 完成之前数据源不会更改?

最佳答案

reloadData始终 在主线程上调用。如果您不这样做,就是崩溃。

好的,但现在我们来谈谈数据的更改和对 reloadData 的调用是如何耦合的。也许你有这样的情况:

background queue:
=================
<networking>
update the data
main queue:
===========
reloadData

您仍然会遇到麻烦,因为尽管对主队列的两次调用不能重叠,但对后台队列的两次调用可以重叠,因为它可能是并发队列。这就是你的比赛条件;数据的更新和数据的重新加载是解耦的。请记住,在重新加载数据期间调用了多个数据源方法,因此它们都需要查看相同数据,否则如果数据不一致,您确实会因某种不一致问题而崩溃调用之间的变化。有了这种架构,这是一个非常现实的可能性。

但是如果后台队列是一个串行队列,并且如果到主队列的步骤是从那个串行队列开始的,那么这种重叠至少是不可能的。所以这将是一个更安全的解决方案:

background queue:
=================
<networking>
single background *serial* queue:
=================================
update the data
main queue:
===========
reloadData

尽管如此,我们处于“共享数据”状态。危险依然存在。没有什么可以阻止数据与所有这些同时被触及一些其他队列。为防止这种情况发生,您需要围绕对数据的每次 访问编写代码,确保访问只发生在一个队列上。毕竟,您的数据结构本身可能不是线程安全的!但是我们已经知道数据源方法将只在主线程上看到数据,因为这就是 reloadData 的工作方式。所以最简单的方法就是制定一个规则,每次对数据的访问都发生在主队列上:

background queue:
=================
<networking>
main queue:
===========
update the data
reloadData

因此,总而言之,如果这就是您现在正在做的事情,那么这是正确的做法。

关于swift - 主线程和 Collectionview.reloadData(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64991690/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com