tableView中的cell是每次出现在屏幕上的时候加载他的内容。so,在加载cell的时候尽量不要做耗时操作,不然在tableView滚动的时候出现卡顿或卡死的情况。
有一种耗时操作是在别的情况下无法解决的。加载较大图片,图片越大,加载越慢,如果一个cell上有多张图片,那么会更加卡顿。这个时候就可以用RunLoop去处理。
tableView重用cell时,是在一次RunLoop循环中处理完成的,如果多张大图,那么就比较耗时。这个时候的处理思路是:一次RunLoop加载一张图片。完成步骤:
1.监听Runloop ---- C语言
-(void)addRunloopObserver{
//获取当前的RunLoop
CFRunLoopRef runloop = CFRunLoopGetCurrent();
//定义一个centext
CFRunLoopObserverContext context = {
0,
( __bridge void *)(self),
&CFRetain,
&CFRelease,
NULL
};
//定义一个观察者
static CFRunLoopObserverRef defaultModeObsever;
//创建观察者
defaultModeObsever = CFRunLoopObserverCreate(NULL,
kCFRunLoopBeforeWaiting,
YES,
NSIntegerMax - 999,
&Callback,
&context
);
//添加当前RunLoop的观察者
CFRunLoopAddObserver(runloop, defaultModeObsever, kCFRunLoopDefaultMode);
//c语言有creat 就需要release
CFRelease(defaultModeObsever);
}
2.监听Runloop后的回调函数,并处理添加到数组中的任务
static void Callback(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info){
ViewController * vc = (__bridge ViewController *)(info);
if (vc.tasks.count == 0) {
return;
}
BOOL result = NO;
while (result == NO && vc.tasks.count) {
//取出任务
RunloopBlock unit = vc.tasks.firstObject;
//执行任务
result = unit();
//干掉第一个任务
[vc.tasks removeObjectAtIndex:0];
//干掉标示
[vc.tasksKeys removeObjectAtIndex:0];
}
}
3.出现在屏幕中cell需要加载的图片添加到任务数组中
-(void)addTask:(RunloopBlock)unit withKey:(id)key{
[self.tasks addObject:unit];
[self.tasksKeys addObject:key];
//保证之前没有显示出来的任务,不再浪费时间加载
if (self.tasks.count > self.max) {
[self.tasks removeObjectAtIndex:0];
[self.tasksKeys removeObjectAtIndex:0];
}
}
注意:在cellForRowAtIndexPath中,掉添加任务的函数
[self addTask:^BOOL{
[ViewController addImage1With:cell];
return YES;
} withKey:indexPath];