这个方法将创建一个 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,去除了前一个版本的黑魔法,增加了预缓存功能。










