ios - 关于RunLoop处理的6类事件问题
ringa_lee
ringa_lee 2017-04-18 09:22:29
[iOS讨论组]

在网上看到一篇文章,出自WeMobileDev

里面对runloop有这样的描述,如下

RunLoop主要处理以下6类事件:

static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__();
static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__();
static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__();

他对这六类事件有如下解释

1.Observer事件,runloop中状态变化时进行通知。(微信卡顿监控就是利用这个事件通知来记录下最近一次main runloop活动时间,在另一个check线程中用定时器检测当前时间距离最后一次活动时间过久来判断在主线程中的处理逻辑耗时和卡主线程)。这里还需要特别注意,CAAnimation是由RunloopObserver触发回调来重绘,接下来会讲到。

2.Block事件,非延迟的NSObject PerformSelector立即调用,dispatch_after立即调用,block回调。

3.Main_Dispatch_Queue事件:GCD中dispatch到main queue的block会被dispatch到main loop执行。

4.Timer事件:延迟的NSObject PerformSelector,延迟的dispatch_after,timer事件。

5.Source0事件:处理如UIEvent,CFSocket这类事件。需要手动触发。触摸事件其实是Source1接收系统事件后在回调 __IOHIDEventSystemClientQueueCallback() 内触发的 Source0,Source0 再触发的 _UIApplicationHandleEventQueue()。source0一定是要唤醒runloop及时响应并执行的,如果runloop此时在休眠等待系统的 mach_msg事件,那么就会通过source1来唤醒runloop执行。

6.Source1事件:处理系统内核的mach_msg事件。(推测CADisplayLink也是这里触发)。

但是我在尝试的过长当中,我没有在xcode的断点后的堆栈信息里看到相关的展示,例如,我GCD一个异步线程,然后切换到主线程,如下:

可以看到,堆栈信息里并没有打印出__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__()

再比如:
它的解释是:
Block事件,非延迟的NSObject PerformSelector立即调用
我做了如下测试:

也是没有看到这个打印
__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__()

是不是我的操作有问题,还是XCode的新特性,隐藏了runloop的堆栈信息呢?

ringa_lee
ringa_lee

ringa_lee

全部回复(1)
天蓬老师

我自己找到答案了,原来不是在左面,而是在下面...给自己一点教训,也是涨经验了...

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号