gpt4 book ai didi

iphone - 如果在滚动期间更新数据源,UITableView 会崩溃

转载 作者:行者123 更新时间:2023-12-03 18:17:51 26 4
gpt4 key购买 nike

我有一个应用程序,其中 UITableView 的数据源由远程服务器的后台线程每 30 秒更新一次。

如果用户滚动 tableView 或 tableView 正在 reloadTableView: 过程中,则会发生崩溃。崩溃的原因是崩溃时表中的行数与重绘开始时的行数不匹配。

当请求的 TableView 单元格超出范围时,会发生另一次崩溃,因为在调用 numberofTableViewCells: 的时间和调用 cellfForRowAtIndexPath 的时间之间,数据模型发生了更改,并且单元格不再存在。

tableView 的数据是从后台线程更新的。当从服务器加载数据时,用户应该仍然能够与 tableView 交互,但现在这会导致崩溃。

更新 tableViewDataSource 时如何阻止 tableView 滚动或重新加载?这种情况的最佳做法是什么?

谢谢。

最佳答案

简单的回答是,您需要缓冲数据模型中的数据,并且仅在表不滚动时使用新数据更新表。这需要在数据模型中完成,因为数据源委托(delegate)不知道数据模型内部有什么或发生了什么变化。

但是,从 UI 设计的角度来看,在用户滚动时主动更新表格会让用户迷失方向。用户会认为他们位于表格的顶部/中间/底部,然后突然发现自己位于底部/顶部/中间。用户会认为他们已经查看了表的某一部分中的所有数据,但实际上该表将添加他们需要查看的内容。例如,如果表是按字母顺序排列的姓名列表,则用户检查所有以“U”开头的姓名,发现没有,然后转到表中的其他位置进行检查。同时,当用户在其他地方查找时,该表会以新名称无形地更新“U”部分。即使用户知道该表是动态更新的(大多数不是),他们也必须不断滚动检查几乎整个表以查看发生了什么变化。

更好的UI设计是给用户更新的能力。在栏中放置“更新”或“新数据可用”按钮,然后将其设置为在新数据到达时显示。单击按钮后,卡住表并更新,然后才让用户恢复交互。在视觉上标记添加的行也是一个很好的设计。

这将使用户界面更易于理解,同时解决崩溃问题。

编辑01:

如果不使用Core Data,才能实现表的实时不可见更新。您需要在调用 – tableView:cellForRowAtIndexPath: 之前卡住调用 – tableView:numberOfRowsInSection– numberOfSectionsInTableView:

由于首先调用 – tableView:numberOfRowsInSection ,因此我会在那里进行调用以首先更新,然后卡住数据模型。这样,数据模型将返回正确数量的部分和行。

我认为您必须将数据模型分为两部分,其中一个部分将缓冲传入的数据,另一个部分将排序数据以进行显示。您的更新方法应将所有最终缓冲数据移至显示数据部分。

此外,您可能需要为用户不移动 table 的时间设置一个计时器。如果表没有被主动操作,计时器应该调用更新方法,然后它应该强制更新。

如果您使用 Core Data,则可以使用 NSFetchedResultController,它的委托(delegate)方法会在数据模型发生更改时通知您。它应该返回实时更新的正确部分和行信息。通过这种方式驱动更新表非常容易。但是,它无法克服数据进入模型太快而导致模型在方法调用之间发生变化的问题。您仍然需要卡住和/或减慢模型速度。但是,您不需要计时器。

核心数据是你最好的选择,但即便如此,它也很难实现,因为你试图做一些违背 UI 的事情,因此 API 不容易支持它。

更新:

回顾这个答案,我发现我忽略了提及 [UITableView beginUpdates] ,这将在添加或删除行时卡住表的配置。它与 [UITableView endUpdates] 配对以包含 UI 中的更改。

关于iphone - 如果在滚动期间更新数据源,UITableView 会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2318445/

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