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