iOS优化UITableViewCell高度计算的一些事儿

2020-01-21 07:40:51于海丽

这个方法将创建一个 Source 0 任务,分发到指定线程的 RunLoop 中,在给定的 Mode 下执行,若指定的 RunLoop 处于休眠状态,则唤醒它处理事件,简单来说就是“睡你xx,起来嗨!”

于是,我们用一个可变数组装载当前所有需要“预缓存”的 index path,每个 RunLoopObserver 回调时都把第一个任务拿出来分发:


NSMutableArray *mutableIndexPathsToBePrecached = self.fd_allIndexPathsToBePrecached.mutableCopy;
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity _) {
 if (mutableIndexPathsToBePrecached.count == 0) {
 CFRunLoopRemoveObserver(runLoop, observer, runLoopMode);
 CFRelease(observer); // 注意释放,否则会造成内存泄露
 return;
 }
 NSIndexPath *indexPath = mutableIndexPathsToBePrecached.firstObject;
 [mutableIndexPathsToBePrecached removeObject:indexPath];
 [self performSelector:@selector(fd_precacheIndexPathIfNeeded:)
   onThread:[NSThread mainThread]
  withObject:indexPath
  waitUntilDone:NO
   modes:@[NSDefaultRunLoopMode]];
});

这样,每个任务都被分配到下个“空闲” RunLoop 迭代中执行,其间但凡有滑动事件开始,Mode 切换成 UITrackingRunLoopMode,所有的“预缓存”任务的分发和执行都会自动暂定,最大程度保证滑动流畅。

PS: 预缓存功能因为下拉刷新的冲突和不明显的收益已经废弃

开始使用UITableView+FDTemplateLayoutCell

如果你觉得这个工具能帮得到你,整合到工程也十分简单。

使用 cocoapods:


pod search UITableView+FDTemplateLayoutCell

写这篇文章时的最新版本为 1.2,去除了前一个版本的黑魔法,增加了预缓存功能。