Skip to content

Commit e1b5025

Browse files
committed
Refactor some precache logic about RunLoop tasks
1 parent f099e8c commit e1b5025

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

Classes/UITableView+FDTemplateLayoutCell.m

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,37 +177,42 @@ - (void)fd_precacheIfNeeded
177177
}
178178

179179
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
180+
180181
// This is a idle mode of RunLoop, when UIScrollView scrolls, it jumps into "UITrackingRunLoopMode"
181182
// and won't perform any cache task to keep a smooth scroll.
182183
CFStringRef runLoopMode = kCFRunLoopDefaultMode;
183184

185+
// Collect all index paths to be precached.
186+
NSMutableArray *allIndexPathsToBePrecached = self.fd_allIndexPathsToBePrecached.mutableCopy;
187+
184188
// Setup a observer to get a perfect moment for precaching tasks.
185189
// We use a "kCFRunLoopBeforeWaiting" state to keep RunLoop has done everything and about to sleep
186190
// (mach_msg_trap), when all tasks finish, it will remove itself.
187191
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler
188192
(kCFAllocatorDefault, kCFRunLoopBeforeWaiting, true, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity _) {
189-
// Collect all index paths to be precached.
190-
NSMutableArray *allIndexPathsToBePrecached = self.fd_allIndexPathsToBePrecached.mutableCopy;
193+
// Remove observer when all precache tasks are done.
191194
if (allIndexPathsToBePrecached.count == 0) {
192195
CFRunLoopRemoveObserver(runLoop, observer, runLoopMode);
193196
return;
194197
}
198+
// Pop first index path record as this RunLoop iteration's task.
199+
NSIndexPath *indexPath = allIndexPathsToBePrecached.firstObject;
200+
[allIndexPathsToBePrecached removeObject:indexPath];
195201

196202
// This method creates a "source0" task in "idle" mode of RunLoop, and will be
197203
// performed in a future RunLoop iteration only when user is not scrolling.
198-
[self performSelector:@selector(fd_precacheOneOfAllIndexPathsToBePrecached:)
204+
[self performSelector:@selector(fd_precacheIndexPathIfNeeded:)
199205
onThread:[NSThread mainThread]
200-
withObject:allIndexPathsToBePrecached
206+
withObject:indexPath
201207
waitUntilDone:NO
202208
modes:@[NSDefaultRunLoopMode]];
203209
});
204210

205211
CFRunLoopAddObserver(runLoop, observer, runLoopMode);
206212
}
207213

208-
- (void)fd_precacheOneOfAllIndexPathsToBePrecached:(NSMutableArray *)allIndexPaths
214+
- (void)fd_precacheIndexPathIfNeeded:(NSIndexPath *)indexPath
209215
{
210-
NSIndexPath *indexPath = allIndexPaths.firstObject;
211216
if (![self.fd_cellHeightCache hasCachedHeightAtIndexPath:indexPath]) {
212217
CGFloat height = [self.delegate tableView:self heightForRowAtIndexPath:indexPath];
213218
[self.fd_cellHeightCache cacheHeight:height byIndexPath:indexPath];
@@ -217,7 +222,6 @@ - (void)fd_precacheOneOfAllIndexPathsToBePrecached:(NSMutableArray *)allIndexPat
217222
@(indexPath.row),
218223
@(height)]];
219224
}
220-
[allIndexPaths removeObjectAtIndex:0];
221225
}
222226

223227
- (NSArray *)fd_allIndexPathsToBePrecached

0 commit comments

Comments
 (0)