runloop学习的一些总结

2016-08-25  本文已影响15人  mengshuobuyi

目前网络上关于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);

切记一定要在主线程!

水平有限,请大家不吝赐教!

上一篇 下一篇

猜你喜欢

热点阅读