代码改变世界

iOS进阶五-RunLoop

2019-05-22 17:56  iCoderHong  阅读(362)  评论(0编辑  收藏  举报

简介

RunLoop 运行循环、跑圈

RunLoop的作用主要体现在三方面:

 1.保持程序持续运行

 2.处理App中的各种事件(比如触摸事件、定时器事件、Selector事件)

 3.节省CPU资源,提高程序性能:该做事的时候做事,该休息的时候休息

 在iOS中访问RunLoop🈶2套API

  • Foundation:NSRunLoop
  • Core Foundation: CFRunLoopRef

NSRunLoop是基于CFRunLoopRef的一层OC包装,因此我们需要研究CFRunLoopRef层面的API(Core Foundation层面)

RunLoop与线程

  • RunLoop保存在全局的Dictionary里,线程作为key,RunLoop作为Value
  • 每条线程都有唯一的一个与之对应的RunLoop 线程创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建

  • 主线程的RunLoop是UIApplicationMain函数获取创建的,子线程默认没有开启RunLoop

  • RunLoop会在线程结束时销毁

RunLoop相关类数据结构

CFRunLoopMode

一个RunLoop包含若干个Mode(RunLoop的运行模式) RunLoop启动时只能选择一个Mode作为currentMode

每个Mode又包含若干个Source0/Source1/Timers/Observers

RunLoop一旦启动,就会监听循环处理当前currentMode下的Source0/Source1/Timers/Observer

常见的2中Mode

  •  kCFRunLoopDefaultMode/NSDefaultRunLoopMode:App的默认Model 通常主线程在这个Mode下运行
  • UITrackingRunLoopModel:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证页面滑动时不受其它Mode影响
事件类型

事件举例 

 Source0

基于Port的线程间通信(NSPortMessage NSPort)

performSelector:onThread:是通过_Source0来处理

Source1

基于Port的线程间通信(NSPortMessage NSPort)

系统事件的捕捉

 Timers

NSTimer

performSelector:withObject:afterDelay:

Observers

用于监听RunLoop的状态

UI刷新(BerforeWaiting)

Autorelease pool(BerforeWaiting)

 CFRunLoopObserversRef

CFRunLoop源码中定义RunLoop状态

给RunLoop添加Observers 监听RunLoop状态

RunLoop切换Mode需要退出当前Loop,再重新选择一个Model进入,对应的两个状态kCFRunLoopEntryKCFRunLoopExit,可以通过滑动UIScrollView切换模式验证

RunLoop的运行逻辑

RunLoop 循环 具体要做的业务如下

 RunLoop的运行逻辑流程图

 

RunLoop休眠的实现原理

 

 

 RunLoop在实际开发中的应用

  • 控制线程声明周期(线程保活)
  • 解决NSTimer在滑动时停止工作问题
  • 监控应用程序卡顿
  • 性能优化 

 

 RunLoop相关的文章推荐