一、runloop线程保活
1.1 线程保活的作用:
使用子线程时,如果任务非常频繁,如检测网络状态,缩放,拖动等触发的事件,切换不同子线程会消耗大量cpu,如果是同一个常驻线程则可以避免该问题
1.2 在线程中启动一个runloop
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runLoopThreadEntryPoint:) object:nil];
[thread start];
//实现线程入口方法:在线程入口方法中,创建并启动一个 RunLoop。例如
- (void)runLoopThreadEntryPoint:(id)object {
@autoreleasepool {
// Create an autoreleased NSRunLoop object
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
self.runloop = runloop;
// Add an input source to the run loop (for example, a timer or a custom input source)
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
// Run the run loop
[runLoop run];
}
}
1.3 插入任务
[NSObject performSelector: @selector(log) onThread: thread withObject: obj waitUntilDone: NO];
[runLoop performBlock:^{
if (block) block();
if (completion) completion();
dispatch_async(dispatch_get_main_queue(), ^{
self.renderTaskCount--;
if (isDrawBlock) [self flush];
});
}];
二、 CADisplayLink 同步屏幕刷新
前面大量任务产生结果,需要密集刷新显示时,可以使用CADisplayLink优化, CADisplayLink 与NStimer类似,不过前者同步屏幕刷新时间,如60hz的调用周期时1/60s
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkCallback:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
- (void)displayLinkCallback:(CADisplayLink *)displayLink {
// 在这里执行需要执行的任务,例如更新界面或者计算动画状态
}
三、其他
在多个任务持续输入或输出数据中,可以添加bool标识,即前一个任务未执行完之前,下一个任务则跳过