UITableView刷新的时候,一般使用的刷新方法就是下面两个:
- (void)reloadData;
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation NS_AVAILABLE_IOS(3_0);
之前一致认为,相比reloadData
,肯定是reloadRowsAtIndexPaths:
方法这种局部刷新的性能更优,所以如果cell比较复杂我会考虑使用reloadRowsAtIndexPaths:
方法刷新tableView
...
直到今天。
项目里面改一个小的业务,有个签到界面,之前其他同事写的逻辑是第一个cell显示日历,下面每一个cell显示一条签到记录,之后让改成下面的签到记录改成h5显示,给的时间比较短,所以不想改动太多,直接把tableView弄成俩cell,上面还是显示日历不动,下面一个cell添加一个WKWebView显示h5的签到记录,问题出现了,每点击一个日期,调用reloadRowsAtIndexPaths
重新刷新单个cell,问题出现了,webView不见了,于是加断点调试,猛然发现reloadRowsAtIndexPaths
并没有重用cell,而是又alloc了一次,之后才会重用,也就是说alloc了两个cell,但是换成reloadData
就不会这样。
猜想
之后经过测试,我有了这样的一个猜想:
-
reloadData
方法应该是把tableView上显示的所有cell全部放到重用池,然后执行cellForRowAtIndexPath
方法时,可以从重用池拿到之前的cell。 -
reloadRowsAtIndexPaths
方法是直接刷新指定的cell,执行cellForRowAtIndexPath
时重用池找不到可重用的cell,于是重新alloc,之后才会把之前的cell放入重用池,所以之后再执行reloadRowsAtIndexPaths
时可以从重用池找到cell,就不会再alloc了。
当然,这只是我的一些猜想,目前还没找到具体的依据。先记录一下,有时间再查详细资料。