美文网首页
Runloop都干啥了

Runloop都干啥了

作者: QG不吃鱼的猫 | 来源:发表于2020-05-12 12:30 被阅读0次

一、Runloop概念

Runloop是通过内部维护的事件循环(Event loop)来对事件/消息进行管理的一个对象。

没有消息处理时,休眠以避免资源的占用,由用户态切换到内核态
有消息需要处理时,立刻被唤醒,由内核态切换到用户态

二、Runloop的数据结构

NSRunLoop(Foundation)是CFRunloop(CoreFoundation)的封装,提供了面向对象的API。

主要涉及五个类:

CFRunloop : Runloop 对象
CFRunLoopMode : 运行模式
CFRunLoopSource :输入源/事件源
CFRunLoopTimer :定时源
CFRunLoopObserver:观察者

1.CFRunLoop

由pthread、currentMode、modes、commonModes、commonModeItems构成。

2.CFRunLoopMode

由name、source0,source1,observers、timers构成。
总共有5种

  • kCFRunLoopDefaultMode:默认模式,主线程时在这个运行模式下运行
  • UITrackingRunLoopMode:跟踪用户交互事件
  • UIInitializationRunLoopMode:在刚启动App时进入的第一个Mode,启动完成后就不再使用
  • GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到
  • kCFRunLoopCommonModes:伪模式,是同步Source/Timer/Observer到多个Mode的一种解决方案

3.CFRunLoopSource

分为source0和source1两种

  • source0
    即非基于port的,也就是用户触发的事件,需要手动唤醒线程,将当前的线程从内核态切换到用户态。如:UIEvent事件。
  • source1
    基于port的,包含了一个mach_port 和一个回调,可以监听系统端口和通过内核接受其他线程发送的消息,能主动唤醒RunLoop,接受分发系统事件,具备唤醒线程的能力。

4.CFRunLoopTimer

基于事件的触发器,基本上说就是NSTimer,在预设的时间点唤醒RunLoop执行回调。因为他是基于RunLoop的,因此不是实时的(因为RunLoop值负责分发源的消息,如果线程正在处理繁重的任务,有可能导致Timer本次延时或者少执行一次。)。

5.CFRunLoopObserver

可以监听一下事件点

  • kCFRunLoopEntry
    RunLoop准备启动
  • kCFRunLoopBeforeTimers
    RunLoop将要处理一些Timer相关事件
  • kCFRunLoopBeforeSources
    RunLoop将要处理一些Source事件
  • kCFRunLoopBeforeWaiting
    RunLoop将要进行休眠状态,即将由用户态切换到内核状态
  • kCFRunLoopAfterWaiting
    RunLoop被唤醒,即从内核态切换到用户态
  • kCFRunLoopExit
    RunLoop退出
  • kCFRunAllActivities
    监听所有状态

6.各数据结构之间的关系

线程和RunLoop一一对应,RunLoop和Mode以一对多,Mode和source、timer、observer也是一对多。

二、Runloop的使用场景

1.autoreleasePool在何时被释放?

App启动后,苹果在主线程RunLoop里注册了两个Observer。
其回调都是_wrapRunLoopWithAutoreleasePoolHandler()。

第一个Observer监视的事件是Entry(即将进入Loop),其回调会调用_objc_autoreleasePoolPush()创建自动释放池,优先级最高,保证创建释放池发生在其他所有回调之前。

第二个Observer监视了两个事件:BeforeWaiting(准备进入休眠)时调用_objc_autoreleasePoolPop()和_objc_autoreleasePoolPush()释放旧的池并创建新池;Exit(即将退出Loop)时调用_objc_autoreleasePoolPop()来释放自动释放池,这个Observer的优先级最低,保证其释放池子的发生在其他回调之后。

2.performSelector的实现原理?

当调用NSObject的performSelector:afterDelay:后,实际上时内部创建了一个Timer并添加到当前线程的RunLoop中。所以如果线程RunLoop,则这个方法会失效。
当调用performSelector:onThread:时,实际上也是创建了一个Timer到对应的线程中,同样,如果对应线程没有RunLoop该方法也会失效。

performSelector:afterDelay:在子线程默认没开启RunLoop,所以不起作用,可以使用GCD:Dispatch_after实现,或者在添加Timer后,启动子线程的RunLoop。

3.解释一下事件响应的过程?

苹果注册了一个Source1(基于mach port的)用来接受系统事件,其回调函数为_IOHIDEventSystemClientQueueCallback().
当一个硬件事件(触摸/锁屏/摇晃等)发生后,首先由IOKit.framework生成一个IOHIDEvent事件并由SpringBoard接收。随后苹果注册的那个Source1就会触发回调,并调用_UIApplicationHandleEventQueue()进行应用内部的分发。
_UIApplicationHandleEventQueue()会把IOHIDEvent处理并包装成UIEvent进行处理或者分发,其中包括识别UIGEsture/处理屏幕旋转/发送给UIWindow等。通常事件比如UIButton点击、touchesBegin/Move/End/Cancle事件都是在这个回调里完成的。
//SpringBoard其实时一个标准的应用程序,用来管理iOS的主屏幕,它时iOS程序中,事件的第一个接受者,只能接受少数的事件,比如:按键(锁屏/静音),触摸、加速、传感器等,随后使用machPort转发给需要的App进程。

4.解释一下手势识别的过程?

当上面的_UIApplicationHandleEventQueue()识别到一个手势时,首先会调用Cancel,将当前的touchBegin/Move/End系统回调打断,随后系统将对应的UIGestureRecognizer标记为待处理。
苹果注册了一个Observer监测BeforeWaiting(Loop即将进入休眠)事件,这个Observer的回调函数是_UIGestureRecognizerUpdateObserver(),其内部会获取所有刚被标记为待处理的GestureRecognizer,并执行GestureRecognizer的回调。
当有UIGestureRecognizer的变化时,这个回调都会进行相应的处理。

5.利用runloop解释一下页面渲染的过程?

当我们调用[UIView setNeedsDisplay]时,这时会调用但前view.layer的[view.layer setNeedsDisplay]方法。
这等于给当前layer打了一个标记,而此时并没有进行绘制工作。而是等当前的RunLoop即将休眠的时候进行绘制工作。
CALayer内部会创建一个BackingStore,用来获取图形上下文,最终CALayer都会将位图提交到BackingStore,提交给GPU,绘制结束。
//CALayer异步绘制待总结。

相关文章

  • Runloop都干啥了

    一、Runloop概念 Runloop是通过内部维护的事件循环(Event loop)来对事件/消息进行管理的一个...

  • 20180402-都干啥了

    回想一下上个周末都干了些啥,周六在家打农药,然后下午出去踏青,去公园逛了逛,看看春的气息,最后去了旁边的驾校看了看...

  • 总结┃寒假都干啥了

    寒假计划在此 白驹过隙,岁月如梭,在无休止的加班以及休假后,寒假居然“so……”的一下就过去了。 循例写个流水账,...

  • 今天你都干啥了

    这一句话给我问蒙圈了,回想这一天好像除了吃饭什么都没有干啊!突然觉得压力好大,这一天天的忙起来就监测监测,工作也没...

  • 《都干啥》

    版权声明 本文首发简书:校长杨羊 转载请注明出处 杨羊的注意力都花哪里了 通俗点 杨羊都干啥了 统而言之 学习和成...

  • 心态摆正了,干啥都顺了!

    人活着 总有不如意和失去, ...

  • 年走了,你干啥了都?

    年假如此匆匆,到了说再见的时候。 仔细想想我都干了啥? 昨天我去人家药店门口称了一下,称完放心了,不担心人家叫我,...

  • 一天都干啥了?

    今天开始记录每天做什么,时间也标记下来。 一天下来,不再感觉自己啥都没做,完全确定自己啥也没做。 我以为自己是看了...

  • 一天都干啥了

    上午去看老妈那,想着搬家随便看个日子,妹子说最起码细致点,查查农历没有禁忌再搬,还别说,还真有不少禁忌。忌这忌那,...

  • 干啥了

    晚上回想今天一天工作,感觉什么也没做。 先是十点前到永和宇宙星收了一个件,骑电动车去广发金融大厦解管,没解管成去金...

网友评论

      本文标题:Runloop都干啥了

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