MJ_RunLoop

允我心安 提交于 2019-12-19 14:53:08

1.RunLoop对象

iOS中有两套API来访问和使用RunLoop

Core Foundation框架:CFRunLoopRef,是开源的

Foundation框架:NSRunLoop,基于CFRunLoopRef的一层OC包装

2.获取RunLoop对象

[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象

CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象

[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象

CFRunLoopGetMain(); // 获得主线程的RunLoop对象

3.RunLoop相关的类

CFRunLoopRef 、CFRunLoopModeRef、CFRunLoopSourceRef 、CFRunLoopTimerRef 、CFRunLoopObserverRef

  • CFRunLoopModeRef

    1>CFRunLoopModeRef代表RunLoop的运行模式

    2> 一个RunLoop包含若干个Mode,每个Mode又包含若干个Source0/Source1/Timer/Observer

    3>RunLoop启动时只能选择其中一个Mode,作为currentMode

    4>如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入,  不同组的Source0/Source1/Timer/Observer能分隔开            来,互不影响

    5>如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出

  • CFRunLoopModeRef

    常见的两种Mode:

    1>kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行

    2>UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

  • CFRunLoopObserverRef

  

添加Observer监听RunLoop的所有状态 

4.RunLoop运行逻辑

  • Source0

    1>触摸事件处理

    2>performSelector:onThread:

  •  Source1

    1>基于Port的线程间通信

    2>系统事件捕捉

  • Timers

    1>NSTimer

    2>performSelector:withObject:afterDelay:

  • Observers

    1.用于监听RunLoop的状态,比如UI刷新和AutoreleasePool释放有可能在BeforeWaiting的时候。

  • RunLoop整个运行逻辑

     01、通知Observers:进入Loop

     02、通知Observers:即将处理Timers

     03、通知Observers:即将处理Sources

     04、处理Blocks 05、处理Source0(可能会再次处理Blocks)

     06、如果存在Source1,就跳转到第8步

     07、通知Observers:开始休眠(等待消息唤醒)

     08、通知Observers:结束休眠(被某个消息唤醒)

           01> 处理Timer

           02> 处理GCD Async To Main Queue

           03> 处理Source1

      09、处理Blocks

      10、根据前面的执行结果,决定如何操作

           01> 回到第02步

           02> 退出Loop

        11、通知Observers:退出Loop

RunLoop休眠的实现原理:

是由用户态切换到内核态实现休眠,用户态只能处理应用层,内核层面的api可以达到线程休眠,while(1)是用户态下的线程阻塞,但是线程没有休眠

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!