目前网络上关于runloop的学习资料不是很多,比较系统的有YYKit的作者写的一篇博文,阳神的博文。下面分享一下自己对这块知识的理解。
runloop与我们日常开发相关并不是太大,但涉及到性能优化这方面,它是无论如何都绕不过去的。
目前我理解的有两方面,第一个是线程保活,管理,另一个是可以把一些可以延后的必需要在主线程完成的工作移到runloop空闲的时候去做。
首先第一方面,借用AFN的代码-
static NSThread *_networkRequestThread = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil];
[_networkRequestThread start];
});
return _networkRequestThread;
@autoreleasepool {
[[NSThread currentThread] setName:@"AFNetworking"];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
}
这边创建了一个单例线程,并插入了一个machPort使它一直存活,然后我们就可以通过访问该线程对任务进行管理,如下
[self performSelector:@selector(dowork) onThread:(你创建的单例线程) withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
第二方面是进行性能优化的,关于runloop的循环这里不多讲了,可以看上面的博客。可以知道,在两个时候runloop是空闲的,一个是RunLoopEntry,一个是RunLoopBeforeWaiting。
我们可以添加一个observer,观察runloop的状态。
CFRunLoopRef runloop = CFRunLoopGetMain();
CFStringRef runloopMode = kCFRunLoopDefaultMode;
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopBeforeWaiting| kCFRunLoopEntry, true, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
if (给一个判断条件) {//移除ob的条件
CFRunLoopRemoveObserver(runloop, observer, runloopMode);
CFRelease(observer);
return;
}
[self performSelector:@selector(testDo:) onThread:[NSThread mainThread] withObject:obj waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
});
CFRunLoopAddObserver(runloop, observer, runloopMode);
切记一定要在主线程!
水平有限,请大家不吝赐教!
网友评论