RunLoop 事件的序列

每次, RunLoop 会操作输入的 events(各种 input source 产生的) 并产生 notifications(给 observers). RunLoop 的处理 events 并且发出 notifications 的具体的顺序如下:
1> 发 notification,通知 Observer,当 RunLoop 开始进入循环的时候
2> 发 notification,通知 Observer, timers 即将被触发(处理 timers 的event)
3> 发 notification,通知 Observer,有其他的非 Port-Based Input Source 即将被触发(non-port-based input source 的 event)
4> 启动非 Port-Based Input Soruce 的事件源的处理函数
5> 如果基于Port的Input Source事件源即将触发时,立即处理该事件,并跳转到9
6> 发 notification,通知 Observer,当前 thread 即将进入睡眠状态
7> 使线程进入睡眠状态直到有以下事件发生 :

1.Port-Based Input Source event  
2.Timer fires  
3.RunLoop 设置的时间超时  
4. RunLoop 被代码显示唤醒  

8> 发 notification,通知 Observer, thread将要被唤醒
9> 处理被触发的事件

1.如果是用户自定义的Timer触发的,处理Timer事件的函数后,重启Run Loop.直接进入步骤2  
2.如果是 input source 事件源有事触发 event,直接传递这个消息  
3.如果runloop 是显示被唤醒并且没有超时,重启 RunLoop. 直接进入步骤2  

10> 发 notification,通知 Observer,Run Loop已经退出

由于 timer 和 input source导致 runloop 给 observer 发送 notification 是在这些事件之前的, 因此可能 notification 发出以后到事件真正的发生中间会有一小段间隔时间, 可以通过 awake-from-sleep 的 notification 来修复确切的时间.

因为 timers 和其他与时间片相关的事件会在runloop 运行时候传递, 有时候会使得循环传递这些事件失灵.典型例子就是, 你在进入 runloop 时候,监听了鼠标的移动路线,然后不断在 app 中请求一些事件.因为你的代码中已经抓住这些事件,并直接处理了,而不是让 app 正常的去 dispatch事件,活动着的 timers 讲将不能被fire,直到你的鼠标追踪事件停止,并把控制权交给 app.

RunLoop 可以使用 runLoop 对象显示的唤醒. 其他的事件也能够唤醒 runloop.例如,给 runloop 添加一个 non-port-based input source,就可以唤醒它,而不必等到其他的事件发生.

转载于:https://my.oschina.net/jlongtian/blog/856597

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值