面试聊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运行逻辑

  1. 通知观察者即将进入RunLoop
  2. 通知观察者即将处理Timer
  3. 通知观察者即将处理source0
  4. 处理source0
  5. 如果有source1,跳至第9步
  6. 通知观察者线程即将进入休眠状态
  7. 线程进入休眠,等待直到以下任一事件发生唤醒线程
  • 某一事件到达基于端口的源
  • 定时器启动
  • RunLoop设置的时间超时
  • RunLoop被显式唤醒
  1. 通知观察者线程即将被唤醒
  2. 处理唤醒时收到的事件
  • 如果用户定义的定时器启动,处理定时器事件并重启RunLoop,跳回步骤2;
  • 如果输入源启动,传递相应消息;
  • 如果RunLoop被显式唤醒且时间未超时,重启RunLoop,跳回步骤2
  1. 通知观察者,即将退出RunLoop

常驻线程

如果经常会在子线程中做一些耗时操作(比如下载文件、后台播放音乐等),最好能让这条线程常驻内存

为当前线程添加一个RunLoop
向该RunLoop中添加一个Port/Source等维持RunLoop的事件循环
启动该RunLoop

你可能感兴趣的:(面试聊iOS:RunLoop)