ios – 为UITableView调用beginUpdates / endUpdates而不是这样做的好处是什么?

我有一个数组,我用于表视图的数据源.在一个间的情况下,我可能需要对这个数据结构进行一些复杂的修改. (例如,我可能需要做的一系列操作是:删除一行,在这里插入一行,在这里插入一个部分,删除另一行,插入另一行,插入另一个部分 – 你得到想法).这很容易做到,对于序列中的每个操作,我只是更新数据源,然后立即对表视图执行相应的更新.换句话说,伪码将如下所示:
[arrayOfArrays updateForOperation1];
[tableView updateForOperation1];

[arrayOfArrays updateForOperation2];
[tableView updateForOperation2];

[arrayOfArrays updateForOperation3];
[tableView updateForOperation3];

[arrayOfArrays updateForOperation4];
[tableView updateForOperation4];

// Etc.

但是,如果要在beginUpdates / endUpdates“块”中包围这些操作,则此代码不再工作.要了解为什么,成像从空的表格视图开始,依次在第一部分的开头插入四行.这是伪码:

[tableView beginUpdates];

[arrayOfArrays insertRowAtIndex:0];
[tableView insertRowAtIndexPath:[row 0,section 0]];

[arrayOfArrays insertRowAtIndex:0];
[tableView insertRowAtIndexPath:[row 0,section 0]];

[tableView endUpdates];

当endUpdates被调用时,表视图发现您正在插入四行,这些行全部与第0行相冲突!

如果我们真的想要保留beginUpdates / endUpdate部分的代码,我们必须做一些复杂的事情. (1)我们在数据源中进行所有更新,而不用更新表视图. (2)我们弄清楚在所有更新之前,所有更新之前的数据源部分如何映射到所有更新后的数据源部分,以确定需要为表视图执行哪些更新. (3)最后,更新表视图.伪代码看起来像这样,以完成我们在上一个示例中尝试做的事情:

oldArrayOfArrays = [self recordStateOfArrayOfArrays];

// Step 1:
[arrayOfArrays insertRowAtIndex:0];
[arrayOfArrays insertRowAtIndex:0];
[arrayOfArrays insertRowAtIndex:0];
[arrayOfArrays insertRowAtIndex:0];

// Step 2:
// Comparing the old and new version of arrayOfArrays,// we find we need to insert these index paths:
// @[[row 0,section 0],//   [row 1,//   [row 2,//   [row 3,section 0]];
indexPathsToInsert = [self compareOldAndNewArrayOfArraysToGetIndexPathsToInsert];

// Step 3:

[tableView beginUpdates];

for (indexPath in indexPathsToInsert) {
    [tableView insertIndexPath:indexPath];
}

[tableView endUpdates];

为什么要这样做为了updateUpdates / endUpdates?该文档说要使用beginUpdates和endUpdates来做两件事情:

>同时动画化一堆插入,删除和其他操作
>“如果您不在此块内进行插入,删除和选择调用,则表属性(如行数)可能会失效. (这真的意味着什么呢?)

但是,如果我不使用beginUpdates / endUpdates,表视图看起来像是同时动画化各种变化,我不认为表视图的内部一致性已被破坏.那么用beginUpdates / endUpdates做复杂的方法有什么好处呢?

解决方法

每次添加/删除表项时,都会调用tableView:numberOfRowsInSection:方法,除非您使用begin / endUpdate来围绕这些调用.如果您的数组和表视图项目不同步,则没有开始/结束调用将抛出异常.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...