面试聊iOS:RunLoop
大家好,我是面试聊iOS的程序员。
这篇文章将和大家分享面试iOS时聊RunLoop一般都可以聊些什么。
抖音搜索 面试聊iOS 观看视频版
相关文章链接
面试聊iOS:内存管理
面试聊iOS:RunTime(一)
面试聊iOS:RunTime(二)
面试聊iOS:Block
面试聊iOS:多线程
面试聊iOS:RunLoop
面试聊iOS:性能优化
什么是RunLoop
默认情况下,线程执行完任务后就会退出,不再执行任务。我们需要采用一种方式来让线程能够不断的处理任务,并且不退出,所有就有了RunLoop。
顾名思义,RunLoop就是一直运行着的循环。
RunLoop实际上是一个对象,这个对象在循环中用来处理程序运行过程中出现的各种事件(比如说touch事件、UI刷新事件、定时器事件、Selector事件),从而保持程序的持续运行。Runloop在没有事件处理时,会让线程进入休眠,只有在接收到事件时才会被唤醒,然后再做出相应的处理。
一条线程对应一个RunLoop对象,主线程的RunLoop对象由系统自动创建。
RunLoop Mode
NSDefaultRunLoopMode
app默认Mode,通常主线程就在该Mode下运行。
NSTrackingRunLoopMode
界面跟踪mode,用于scrollView追踪触摸滑动,保证界面滑动时不受其他Mode影响。
UIInitializationRunLoopMode
在刚启动app时进入的第一个Mode,启动完成后就不再使用。
GSEventReceiveRunLoopMode
接收系统事件的内部Mode,通常用不到。
NSRunLoopCommonModes
这是一个占位Mode,不是一个真正的Mode,会同时处理默认模式和UI模式中的事件。
RunLoop Source
定时源,基于时间的触发器,基本上就是NSTimer
NSTimer默认被加入RunLoop的default mode下
source0:非基于Port的源,基本就是应用层事件,比如点击事件
source1:基于Port的源,通过内核和其他线程通信,接收、分发系统事件
我们点击app内的某个按钮,先触摸到屏幕(硬件),屏幕表面的事件会先封装成Event传递给source1(mach_port),source1唤醒runloop,让后将Event分发给source0处理。
RunLoop Observer
CFRunLoopObserverRef,监听RunLoop的状态改变
即将进入Loop:1
即将处理Timer:2
即将进入source:4
即将进入休眠:32
即将从休眠中唤醒:64
即将从Loop中退出:128
监听全部状态改变
RunLoop运行逻辑
- 通知观察者即将进入RunLoop
- 通知观察者即将处理Timer
- 通知观察者即将处理source0
- 处理source0
- 如果有source1,跳至第9步
- 通知观察者线程即将进入休眠状态
- 线程进入休眠,等待直到以下任一事件发生唤醒线程
- 某一事件到达基于端口的源
- 定时器启动
- RunLoop设置的时间超时
- RunLoop被显式唤醒
- 通知观察者线程即将被唤醒
- 处理唤醒时收到的事件
- 如果用户定义的定时器启动,处理定时器事件并重启RunLoop,跳回步骤2;
- 如果输入源启动,传递相应消息;
- 如果RunLoop被显式唤醒且时间未超时,重启RunLoop,跳回步骤2
- 通知观察者,即将退出RunLoop
常驻线程
如果经常会在子线程中做一些耗时操作(比如下载文件、后台播放音乐等),最好能让这条线程常驻内存
为当前线程添加一个RunLoop
向该RunLoop中添加一个Port/Source等维持RunLoop的事件循环
启动该RunLoop