RunLoop

作者: hxxxs | 来源:发表于2018-12-17 11:27 被阅读0次
    runloop.png

    概念

    运行循环(死循环)

    作用

    • 保证程序持续运行
    • 处理app中各种事件(触摸事件,定时器事件,selector事件)
    • 节省cpu资源,提高程序性能

    线程与runloop

    • 每个线程中都有与之对应的runloop
    • 主线程runloop默认开启,子线程runloop需要主动创建
    • 第一次获取的时候创建,在线程结束时销毁

    启动

    runloop在启动时会选择一种运行模式(NSRunLoopMode),判断mode中是否包含source/timer,如果不包含则判断运行模式为空,runloop会直接退出

    CFRunLoopSourceRef

    • source0: 用户触发
    • source1: 基于端口(port)

    CFRunLoopObserverRef

    • kCFRunLoopEntry = (1UL << 0), // 启动
    • kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理timer事件
    • kCFRunLoopBeforeSources = (1UL << 2), // 即将处理source事件
    • kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠状态
    • kCFRunLoopAfterWaiting = (1UL << 6), // 结束休眠状态
    • kCFRunLoopExit = (1UL << 7), // 退出
    • kCFRunLoopAllActivities = 0x0FFFFFFFU // 所有状态
    //  创建观察者
        CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
            switch (activity) {
                case kCFRunLoopEntry:
                    NSLog(@"runloop启动");
                    break;
                case kCFRunLoopBeforeTimers:
                    NSLog(@"runloop即将处理timer事件");
                    break;
                case kCFRunLoopBeforeSources:
                    NSLog(@"runloop即将处理source事件");
                    break;
                case kCFRunLoopBeforeWaiting:
                    NSLog(@"runloop即将进入休眠状态");
                    break;
                case kCFRunLoopAfterWaiting:
                    NSLog(@"runloop结束休眠状态");
                    break;
                case kCFRunLoopExit:
                    NSLog(@"runloop退出");
                    break;
                default:
                    break;
            }
        });
        
        //  监听runloop
        CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
    

    运行过程

    WX20181217-111539.png

    如何开启一个常驻线程

    核心代码

    - (NSThread *)thread {
        if (_thread == nil) {
            _thread = [[NSThread alloc] initWithBlock:^{
                [NSRunLoop.currentRunLoop addPort:NSPort.port forMode:NSDefaultRunLoopMode];
                [NSRunLoop.currentRunLoop run];
            }];
            _thread.name = @"常驻线程";
            [_thread start];
        }
        return _thread;
    }
    

    内部自动释放池

    • 第一次创建:runloop启动的时候创建
    • 自动释放池销毁:runloop退出的时候销毁
    • 其他的时候创建及销毁:runloop进入休眠状态的时候会先销毁上一个自动释放池,创建新的自动释放池

    仅作为个人学习使用,侵权请告知

    相关文章

      网友评论

          本文标题:RunLoop

          本文链接:https://www.haomeiwen.com/subject/igmtkqtx.html