@@ -177,37 +177,42 @@ - (void)fd_precacheIfNeeded
177
177
}
178
178
179
179
CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop ] getCFRunLoop ];
180
+
180
181
// This is a idle mode of RunLoop, when UIScrollView scrolls, it jumps into "UITrackingRunLoopMode"
181
182
// and won't perform any cache task to keep a smooth scroll.
182
183
CFStringRef runLoopMode = kCFRunLoopDefaultMode ;
183
184
185
+ // Collect all index paths to be precached.
186
+ NSMutableArray *allIndexPathsToBePrecached = self.fd_allIndexPathsToBePrecached .mutableCopy ;
187
+
184
188
// Setup a observer to get a perfect moment for precaching tasks.
185
189
// We use a "kCFRunLoopBeforeWaiting" state to keep RunLoop has done everything and about to sleep
186
190
// (mach_msg_trap), when all tasks finish, it will remove itself.
187
191
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler
188
192
(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.
191
194
if (allIndexPathsToBePrecached.count == 0 ) {
192
195
CFRunLoopRemoveObserver (runLoop, observer, runLoopMode);
193
196
return ;
194
197
}
198
+ // Pop first index path record as this RunLoop iteration's task.
199
+ NSIndexPath *indexPath = allIndexPathsToBePrecached.firstObject ;
200
+ [allIndexPathsToBePrecached removeObject: indexPath];
195
201
196
202
// This method creates a "source0" task in "idle" mode of RunLoop, and will be
197
203
// performed in a future RunLoop iteration only when user is not scrolling.
198
- [self performSelector: @selector (fd_precacheOneOfAllIndexPathsToBePrecached : )
204
+ [self performSelector: @selector (fd_precacheIndexPathIfNeeded : )
199
205
onThread: [NSThread mainThread ]
200
- withObject: allIndexPathsToBePrecached
206
+ withObject: indexPath
201
207
waitUntilDone: NO
202
208
modes: @[NSDefaultRunLoopMode ]];
203
209
});
204
210
205
211
CFRunLoopAddObserver (runLoop, observer, runLoopMode);
206
212
}
207
213
208
- - (void )fd_precacheOneOfAllIndexPathsToBePrecached : ( NSMutableArray *)allIndexPaths
214
+ - (void )fd_precacheIndexPathIfNeeded : ( NSIndexPath *)indexPath
209
215
{
210
- NSIndexPath *indexPath = allIndexPaths.firstObject ;
211
216
if (![self .fd_cellHeightCache hasCachedHeightAtIndexPath: indexPath]) {
212
217
CGFloat height = [self .delegate tableView: self heightForRowAtIndexPath: indexPath];
213
218
[self .fd_cellHeightCache cacheHeight: height byIndexPath: indexPath];
@@ -217,7 +222,6 @@ - (void)fd_precacheOneOfAllIndexPathsToBePrecached:(NSMutableArray *)allIndexPat
217
222
@(indexPath.row),
218
223
@(height)]];
219
224
}
220
- [allIndexPaths removeObjectAtIndex: 0 ];
221
225
}
222
226
223
227
- (NSArray *)fd_allIndexPathsToBePrecached
0 commit comments