美文网首页
Runloop应用

Runloop应用

作者: 凌云01 | 来源:发表于2020-09-12 23:50 被阅读0次

    1、什么是RunLoop?
    2、main函数为什么一直不退出呢?
    3、RunLoop是怎么维护的循环?

    什么是RunLoop?
    RunLoop是通过内部维护的一个事件循环来对事件/消息进行管理的一个对象。
    目的是:

    • 没有消息处理时,休眠以避免资源占用。同时会对线程由用户态切换到内核态。
    • 当有消息进行处理时,立即被唤醒。 会对线程通内核态到用户态的切换,同时线程会被唤醒。

    main函数为什么能保持不退出呢?
    因为在main函数启动后,在内部会调用UIApplicationMain函数,在这个函数内部实际上会启动主线程的一个运行循环即RunLoop,RunLoop可以接受一些事件/消息,并对这些事件/消息进行处理,处理完之后再继续进行等待,这里循环不单单的是一个while循环,而是用户态和内核态之间的相互切换。

    RunLoop是怎么维护的循环?
    RunLoop是CFRunLoop的封装,提供面向对象的API。
    在RunLoop中有五大类

    • CFRunLoop
    • CFRunLoopMode
    • Source/Timer/Observer
    CFRunLoop.png

    其中

    • source0 事件 需要手动唤醒线程
    • source1 事件 具备唤醒线程的能力

    CFRunLoopObserver
    检测时间点:

    • kCFRunLoopEntry
    • kCFRunLoopTimes
    • kCFRunLoopObservers
    • kCFRunLoopBeforeWaiting
    • kCFRunLoopAfterWaiting
    • kCFRunLoopExit

    RunLoop与线程时一一对应的关系,RunLoop与mode是一对多,mode和Source/Timer/Observer是一对多


    CFRunLoopMode.png

    commonMode特殊性:

    • commonMode不是实际存在的一种mode
    • 是同步Source/Timer/Observer到多个Mode的一种方案。

    事件循环的实现机制
    点击App图标,系统是如何进行启动,休眠和退出的?

    RunLoop事件循环机制.jpg
    • 系统启动后,会先执行main函数
    • 在main函数内部会调用UIApplicationMain函数,启动主线程的RunLoop
    • 通知Observe将要处理Timer/Source0事件
    • 处理source0事件
    • 如果有source1事件要处理,那么处理唤醒时收到的消息
    • 如果没有事件要处理了,通知observe线程进入休眠,等待唤醒
    • 当线程RunLoop接受到Source1,Timer事件或者外部手动唤醒,这时通过Mach-Port线程会被唤醒,从内核态进入到用户态,处理事件
    • 当线程退出时,会通知observe退出RunLoop

    RunLoop核心

    RunLoop核心.jpg

    相关文章

      网友评论

          本文标题:Runloop应用

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