業(yè)務(wù)場(chǎng)景
1.最近發(fā)現(xiàn)線上crash率升高了很多。定位到app分類(lèi)頁(yè)面切換分類(lèi)reloadData后tableView滾動(dòng)到指定row會(huì)crash
2.購(gòu)物車(chē)中點(diǎn)擊加號(hào)請(qǐng)求邏輯后再次點(diǎn)擊會(huì)獲取不到正確的cell
crash信息
[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (1) beyond bounds (0) for section (0).
發(fā)現(xiàn)切換分類(lèi)后頁(yè)面進(jìn)行reloadData直接進(jìn)行滾動(dòng)到指定位置的section和row時(shí)候沒(méi)有第一個(gè)row導(dǎo)致越界閃退
crash原因
reloadData代碼執(zhí)行后會(huì)調(diào)用tableview的數(shù)據(jù)源協(xié)議更新tableview朗徊。而我們?cè)趓eloadData后面執(zhí)行的滾動(dòng)代碼或者獲取cell代碼會(huì)立即執(zhí)行偎漫。當(dāng)我們數(shù)據(jù)量很大的時(shí)候象踊,一個(gè)runloop周期還在執(zhí)行,頁(yè)面沒(méi)有布局完成杯矩。導(dǎo)致reloadData后面的代碼執(zhí)行出現(xiàn)異常。等布局完成再去執(zhí)行后續(xù)代碼獲取正確的cell或者滾動(dòng)指定位置就可以正常了
解決方案
1.reloadData后面代碼排隊(duì)執(zhí)行
[self.tableView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
//刷新完成魂务,執(zhí)行后續(xù)代碼
});
2.強(qiáng)制重繪并等待完成
[self.tableView reloadData];
[self.tableView layoutIfNeeded];
//執(zhí)行后續(xù)代碼