RunLoop

142 阅读2分钟

RunLoop

  • 概念
  • 数据结构
  • 事件/循环机制
  • RunLoop与NSTimer
  • RunLoop与多线程

概念(什么是RunLoop)

  • RunLoop是通过内部维护的事件循环来对事件/消息进行管理的一个对象

事件循环(Event Loop)

  • 没有消息需要处理时,休眠以避免资源占用
  • 有消息需要处理时,立刻被唤醒
没有消息需要处理时,休眠以避免资源占用 (状态切换是怎样的)

image.png

有消息需要处理时,立刻被唤醒

image.png

什么是RunLoop?

  • UIApplicationMain维持的事件循环

image.png

数据结构

NSRunLoop是CFRunLoop的封装,提供了面向对象的API.

  • CFRunLoop
  • CFRunLoopMode
  • Source/Timer/Observer

源码地址:

CFRunLoop
  • pthread ==> --对应(RunLoop和线程的关系)
  • currentMode => CFRunLoopMode
  • modes => NSMutableSet<CFRunLoopMode*>
  • commonModes => NSMutableSet<NSString*>
  • commonModeItems =>
commonModeItems

image.png

CFRunLoopMode
  • name => NSDefaultRunLoopMode
  • sources0 => NSMutableSet
  • sources1 => NSMutableSet
  • observers => NSMutableArray
  • timers => NSMutableArray
CFRunLoopSource
  • source0 (需要手动唤醒线程)
  • source1 (具备唤醒线程的能力)
CFRunLoopTimer
  • 基于事件的定时器(和NSTimer是toll-fress bridged的)
CFRunLoopObserver
观测时间点
  • kCFRunLoopEntry
  • kCFRunLoopBeforeTimers
  • kCFRunLoopBeforeSources
  • kCFRunLoopBeforeWaiting
  • kCFRunLoopAfterWaiting
  • kCFRunLoopExit

各个数据结构之间的关系

image.png

RunLoop的Mode

image.png

CommonMode的特殊性
NSRunLoopCommonModes
  • CommonMode不是实际存在的一种Mode.
  • 是同步Source/Timer/Observer到多个Mode中的一种技术解决方案。

事件/循环机制(事件循环的实现机制)

  • void CFRunLoopRun()

image.png

RunLoop的核心

image.png

RunLoop与NSTimer

滑动TableView的时候我们的定时器还会生效吗?

image.png

把timer添加到commonMode,核心代码如下:

void CFRunLoopAddTimer(runLoop,timer,commonMode)

RunLoop与多线程

  • 线程是和RunLoop一一对应的。
  • 自己创建的线程默认是没有RunLoop的。
怎样实现一个常驻线程
  • 为当前线程开启一个RunLoop。
  • 向该RunLoop中添加一个Port/Source等维持RunLoop的事件循环。
  • 启动该RunLoop。
  • 代码实现。

RunLoop面试总结

  • 什么是RunLoop,它是怎样做到有事做事,没事休息的?
  • RunLoop与线程是怎样的关系?
  • 如何实现一个常驻线程?
  • 怎样保证子线程数据回来更新UI的时候不打断用户的滑动操作?