UITableView 在 iOS14 上又遇到坑了
之前項(xiàng)目中有使用到 UITableView reloadRowsAtIndexPaths:withRowAnimation: 方法刷新列表,而且實(shí)際效果也一直很正常。但是,自從升級(jí)了 Xcode12 并在 iOS14 設(shè)備上運(yùn)行之后,發(fā)現(xiàn)閃退了。
經(jīng)過了一番調(diào)試,發(fā)現(xiàn)最后的問題在于 [NSIndexPath indexPathForRow:-1 inSection:0]。當(dāng)使用 -1 初始化時(shí),就會(huì)出現(xiàn)閃退,閃退日志如下:
2020-10-09 17:18:18.443449+0800 TestReloadRowOfTableView[7447:586166] *** Assertion failure in void _UIAssertValidUpdateIndexPath(NSIndexPath * _Nullable __strong)(), UITableViewSupport.m:2736
2020-10-09 17:18:18.447428+0800 TestReloadRowOfTableView[7447:586166] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Attempted to perform update with invalid index path: <NSIndexPath: 0x281952700> {length = 2, path = 0 - 18446744073709551615}'
那這里的 18446744073709551615 是什么呢?
先看一下 API
+ (instancetype)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;
注意,這里的參數(shù) row section 都是 NSInteger 類型,那我使用 -1 也沒有什么問題,但是在實(shí)際情況下,展示出來的不會(huì)出現(xiàn)負(fù)數(shù)的情況。而且,使用負(fù)數(shù)初始化會(huì)自動(dòng)轉(zhuǎn)換成正數(shù)(iOS13 iOS14 都是一樣)。
NSInteger row = -1;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
NSLog(@"todo --- %ld ---- %@", (long)row, indexPath);
2020-10-09 17:38:18.842176+0800 TestReloadRowOfTableView[7482:593029] todo --- -1 ---- <NSIndexPath: 0x2809ac740> {length = 2, path = 0 - 18446744073709551615}
也就是說,在 iOS14 上增加了一層判斷,當(dāng)遇到不符合實(shí)際的索引時(shí),就會(huì)拋出異常。
所以正常開發(fā)中,如果已知某些情況不會(huì)出現(xiàn),就不要再去使用了,防止后面的更新維護(hù)出現(xiàn)新的坑。
測(cè)試代碼在這里。