ios TableView reloadData 与 beginUpdates 和 endUpdates

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8174017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:27:06  来源:igfitidea点击:

TableView reloadData vs. beginUpdates & endUpdates

iosobjective-creloaddata

提问by Tobias Tovedal

I got a tricky problem regarding updating my TableView, i get different results using different methods of updating it, let me explain:

我在更新 TableView 时遇到了一个棘手的问题,使用不同的更新方法得到不同的结果,让我解释一下:

Situation 1:I use [tbl reloadData];where tblis my TableView, to update the TableView - works as intended.

情况 1:我使用我的 TableView[tbl reloadData];在哪里tbl更新 TableView - 按预期工作。

Situation 2:I use:

情况2:我使用:

[tbl beginUpdates];
[tbl reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight];
[tbl endUpdates];

Where tblis my TableView, and indexPathsis an array containing all the indexPaths present in the TableView. Now the array is fine, it contains all the correct indexPaths (double and triple checked) but for some reason - this does not work as intended.

tbl我的 TableView在哪里,indexPaths是一个包含 TableView 中存在的所有 indexPath 的数组。现在数组很好,它包含所有正确的索引路径(双重和三重检查),但由于某种原因 - 这不能按预期工作。

Now I realize that this is an X-Y problem (where I ask for Y but my problem is really X because I think solving Y will solve X) and thats only because I feel it's a bit complicated explaining X (the consequence of said above problem) in an easy way, so I'd rather refrain from that if possible.

现在我意识到这是一个 XY 问题(我要求 Y 但我的问题实际上是 X,因为我认为解决 Y 将解决 X)这只是因为我觉得解释 X 有点复杂(上述问题的后果)以一种简单的方式,所以如果可能的话,我宁愿避免这样做。

So, down to my question:Is there a difference between the two ways of updating the TableView (aside from the animation bit of course) or should I suspect the problem to lay elsewhere?

所以,归结为我的问题:更新 TableView 的两种方式(当然除了动画位)之间有区别还是我应该怀疑问题出在其他地方?

EDIT:Okay, I'll try to explain what the symptoms are:

编辑:好的,我将尝试解释症状是什么:

In the cellForRowAtIndexPath-method I add a button to each cell with an assigned tag which is equal to the cell's indexPath row, like such:

cellForRowAtIndexPath-method 中,我向每个单元格添加一个按钮,并为其分配一个标签,该标签等于单元格的 indexPath 行,如下所示:

btn.tag = indexPath.row;

The reason I do this is so I can identify each button as they all call the same function:

我这样做的原因是我可以识别每个按钮,因为它们都调用相同的函数:

- (void)btnPressed:(id)sender

When I then update the cells - because some values in the cells have changed - Situation 1 makes everything work fine, Situation 2 however - mixes up the tags so the next time one of the buttons are pressed, they no longer have the correct tags.

当我然后更新单元格时 - 因为单元格中的某些值已更改 - 情况 1 使一切正常,但是情况 2 - 混淆了标签,因此下次按下其中一个按钮时,它们不再具有正确的标签。

The mix-up does appear random to me, but the randomization occurs differently depending on which cells button I press first. I hope this clarifies my problem.

这种混淆对我来说确实是随机的,但随机化的发生方式因我首先按下的单元格按钮而异。我希望这能澄清我的问题。

回答by Mundi

From the UITableViewdocumentation

UITableView文档

beginUpdates
Begin a series of method calls that insert, delete, or select rows and sections of the receiver.

beginUpdates
开始一系列方法调用,用于插入、删除或选择接收器的行和部分。

That means, you should not use this unless you are inserting, deleting or selecting. You are doing neither of these.

这意味着,除非您要插入、删除或选择,否则不应使用它。你没有做这些。

Also, you should end beginUpdateswith endUpdates, not reloadData. Documentation:

此外,您应该beginUpdatesendUpdates,结束,而不是reloadData。文档:

This group of methods must conclude with an invocation of endUpdates.

这组方法必须以调用 endUpdates 结束。

回答by Leo

The first difference between reloadDataand reloadRowsAtIndexPathsis that there are 2 UITableViewCellobjects allocated simulteaneosuly for the same indexPath when doing reloadRowsAtIndexPaths(because the tableview 'blends' in the the new cell) . This is sometimes not foreseen by the code in cellForRowAtIndexPath.The surprise comes from the fact that even if a cell was already allocated for a particular cell identfier the table view does not give you back this cell in dequeueReusableCellWithIdentifierwhen calling reloadRowsAtIndexPaths, instead it returns nil. In contradiction reloadDatareuses the cells it already allocated .

reloadData和之间的第一个区别reloadRowsAtIndexPaths是,UITableViewCell在执行时为相同的 indexPath 同时分配了2 个对象reloadRowsAtIndexPaths(因为 tableview 在新单元格中“混合”)。中的代码有时没有预见到这一点cellForRowAtIndexPath。令人惊讶的是,即使已经为特定的单元格标识符分配了一个单元格,表格视图在dequeueReusableCellWithIdentifier调用 时也不会返回该单元格reloadRowsAtIndexPaths,而是返回 nil。相反,reloadData重用它已经分配的单元。

The 2nd difference is that endUpdatesafter reloadRowsAtIndexPathsdirectly calls cellForRowAtIndexPath(if you set a breakpoint there,endUpdatesis visible in the stack trace) whereas reloadDataschedules the calls to cellForRowAtIndexPathat a later time (not visible in the stack trace).

第二个区别是endUpdatesreloadRowsAtIndexPaths直接调用之后cellForRowAtIndexPath(如果在那里设置断点,endUpdates则在堆栈跟踪中可见)而 reloadData将调用安排cellForRowAtIndexPath在稍后的时间(在堆栈跟踪中不可见)。

However you would need to post a bit more code to give us insight what you are doing there. In principle the indexPaths of the new cells are identical to the old ones also with reloadRowsAtIndexPathsas long as you don't delete or insert rows.

但是,您需要发布更多代码才能让我们了解您在那里做什么。原则上,新单元格的 indexPaths 与旧单元格相同,reloadRowsAtIndexPaths只要您不删除或插入行。

回答by gfxcc

Call this method if you want subsequent insertions, deletion, and selection operations (for example, cellForRowAtIndexPath: and indexPathsForVisibleRows) to be animated simultaneously.

如果您希望后续的插入、删除和选择操作(例如,cellForRowAtIndexPath: 和 indexPathsForVisibleRows)同时进行动画处理,请调用此方法。

I think this is what you want. beginUpdates & endUpdates can change the UItableview with animation.

我想这就是你想要的。beginUpdates 和 endUpdates 可以用动画改变 UItableview。