这是我的情景:
我有一个带标签的单元格。当我第一次加载单元格时,模型可能没有标签所需的数据...所以当我发现(通过委托调用)模型刚刚获得标签数据或标签数据已更改时,我可以重新加载特定的单元格。我需要重新加载单元格的原因(而不仅仅是设置标签的文本)是它的高度可能会根据标签是否有文字而改变。
以下是我在委托电话中所做的事情:
- (void)modelLabelDataDidChangeForModel:(NSString *)modelId
{
NSIndexPath *indexPath = [self indexPathForModel:modelId]; // Local method to get index path.
MyCell *cell = (MyCell *) [self.table cellForRowAtIndexPath:indexPath];
if (cell) {
[self.table beginUpdates];
[cell updateMostImportantContent];
[self.table reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.table endUpdates];
}
}
我在*** Assertion failure in -[UITableView _endCellAnimationsWithContext:]
遇到了崩溃(endUpdates
)因为它说更新后的行数与更新前的行数不匹配(因为我在更新块期间没有显式添加/删除任何行;我只是重新加载了1行。
所以这让我觉得模型可能同时进行了2次更改:标签数据正在改变1个项目(因此我的委托调用),但随后还有一个项目被添加到模型中(因此崩溃)。
所以这让我想一想,如何判断我是否需要拨打reloadData
或者我是否可以使用reloadRowsAtIndexPaths:@[indexPath]
重新加载1个单元格?
我是否必须自己跟踪模型,或者我可以使用表格视图来确定这一点并避免崩溃?
我的目标是提高效率:在需要时拨打reloadData
,但在可以的时候拨打reloadRowsAtIndexPath:@[indexPath]
。
答案 0 :(得分:0)
来自文档:
在beginUpdates和endUpdates方法定义的动画块中调用此方法时,其行为与deleteRowsAtIndexPaths:withRowAnimation:类似。 UITableView传递给方法的索引在任何更新之前在表视图的状态中指定。无论动画块中的插入,删除和重新加载方法调用的顺序如何,都会发生这种情况。
在我看来,您不需要或不需要这种电话或方法。您正在更新单个索引。
如果您确实想要更新多个索引,则应通过创建要更新的索引数组来进行不同的排列,然后在完成数据更新时使用beginUpdates
/ endUpdates
系列。< / p>
答案 1 :(得分:0)
-endUpdates
方法强制UITableView
重新计算所有可见单元格的高度。在此之前,它会验证当前显示的数据和调用的一致性
- numberOfSectionsInTableView:
- tableView:numberOfRowsInSection:
dataSource
的方法。
当您不致电-reloadData
时,UITableView
依赖于之前收集的数据(例如,部分数量,部分中的行数)是相同的。
当它不相同时,你会得到断言和崩溃。
为了使您的数据与UITableView
的状态保持一致,您必须在beginUpdates
/ {{1}内删除/插入对象消失或新出现的索引路径上的单元格阻止。