attempt to delete row 44 from section 0 which only contains 0 rows before the update
導致的崩潰
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
[cell setData:dc.attachments[indexPath.row] andReload:^{
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
}
我們通過reloadRowsAtIndexPaths進行更新某個或者某幾個Cell的時候,在tableView內(nèi)部先刪除該Cell,再進行重新創(chuàng)建,如果我們在更新Cell的時候如果該Cell是不存在的就會Crash,attempt to delete row 10 from section 0 which only contains 0 rows before the update(試圖刪除不存在的Cell)
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
如何解決這個問題呢
1、通過使用reloadData進行完全重新加載;
2、判斷該Cell是否存在,存在再進行reloadRowsAtIndexPaths,這樣就可以避免Crash
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (cell) {
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
-》因為此處是datasource中的data變化了。
-》所以不應該調(diào)用reloadRowsAtIndexPaths,而應該直接用reloadData???
-》但是不會導致效率很低嗎?
有點看懂了:
此處是:
對于tableView的datasource的數(shù)組:
conversationItemList
最開始conversationItemList是空的,count是0
此處之前已經(jīng)調(diào)用了:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("ConversationViewController numberOfRowsInSection")
return conversationItemList.count
}
所以當時是numberOfRowsInSection返回的是0
而此處雖然是已經(jīng)添加數(shù)據(jù)了:
if conversationItemList.count == 0 {
conversationItemList.append(newConversationItem)
}
else {
conversationItemList.insert(newConversationItem, atIndex: newInsertItemIdx)
}
但是此時tableView并不知道你的數(shù)據(jù)源變化了
-》所以此時調(diào)用reloadRowsAtIndexPaths,發(fā)現(xiàn):
section 0中,并沒有數(shù)據(jù)
而reload需要
先刪除delete
再添加add
所以此時delete不存在的row的話,就報錯了。
-》所以,此處應該是先調(diào)用reloadData
-》讓系統(tǒng)知道數(shù)據(jù)變化了。
iphone – Crash on reloadRowsAtIndexPath but not on reloadData – Stack Overflow
中的解釋,也和我猜的一樣: