Runloop

作者: 请叫我小鹏哥儿 | 来源:发表于2023-04-22 16:41 被阅读0次

本质

RunLoop本质上是一个对象,这个对象可以保持程序的持续运行并且处理程序中的各种事件(如触摸事件,定时器时间,selector事件).
RunLoop没有事情处理时就会使线程进入睡眠状态.这样可以节省CPU资源,提高程序性能.

和线程的关系

线程用来执行一个或者多个任务,执行完成后就会退出,再有任务也无法继续执行。
runloop,让线程不断的执行任务,当没有任务的时候,进入休眠状态,等待任务的到来。
每条线程都有唯一的一个RunLoop对象。
RunLoop保存在一个全局的 Dictionary里,线程作为key, RunLoop作为 value。
线程刚创建时并没有 RunLoop对象, RunLoop会在第一次获取它时创建。
RunLoop会在线程结束时销毁。
主线程的 RunLoop已经自动获取,子线程默认没有开启 Runloop。

底层数据结构

RunLoop的数据结构主要有三种:
CFRunLoop、CFRunLoopMode、Source/Timer/Observer


CFRunLoop.png
CFRunLoopMode.png
Source:Timer:Observer.png

几种运行模式(mode)?每个运行模式下面的 CFRunloopMode 是哪些?他们分别是什么职责?

  1. kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
  2. UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
  3. UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用,会切换到kCFRunLoopDefaultMode
  4. GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
  5. kCFRunLoopCommonModes: 这是一个占位用的Mode,作为标记kCFRunLoopDefaultMode和UITrackingRunLoopMode用,并不是一种真正的Mode

监听状态有哪几种

  1. kCFRunLoopEntry:RunLoop进入运行循环状态。
  2. kCFRunLoopExit:RunLoop退出运行循环状态。
  3. kCFRunLoopBeforeTimers:RunLoop即将处理定时器事件。
  4. kCFRunLoopBeforeSources:RunLoop即将处理事件源事件。
  5. kCFRunLoopBeforeWaiting:RunLoop即将进入睡眠等待状态。
  6. kCFRunLoopAfterWaiting:RunLoop被唤醒并处理完事件后即将进入下一个循环状态。
  7. kCFRunLoopAllActivities:监听所有状态。

工作流程

流程.png
  1. 通知 observer,进入runloop
  2. 通知 observer,即将处理 timer 事件
  3. 通知 observer,即将处理 source 事件
  4. 处理block,runloop 是可以添加 block 的(CFRunLoopPerformBlock(<#CFRunLoopRef rl#>, <#CFTypeRef mode#>, <#^(void)block#>))
  5. 处理 source 0
  6. 处理 source1事件,如果存在就处理,跳转到第8
  7. 通知 observer 即将休眠
  8. 通知 observer 结束休眠(timer 事件,source1 事件等)
  9. 然后根据前面的执行结果,决定是否再次循环

应用场景

保证线程的长时间存活
滚动视图流畅性优化
让Timer正常运转
事件响应、手势识别、界面刷新、AutoreleasePool自动释放池、NSTimer、PerformSelecter、GCD、网络请求底层等都用到了RunLoop

Source0, Source1

相关文章

网友评论

      本文标题:Runloop

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