RunLoop

2018-04-30  本文已影响8人  我把今生当成了来世

我们从字面意思可以看出:运行循环,跑圈。

基本作用

由于main函数中UIApplicationMain函数内部启动了一个RunLoop,永远不会返回,所以程序不会马上退出,保持持续运行状态。

  • 默认启动的RunLoop跟主线程是相关联的

RunLoop对象

Foundation -> NSRunLoop
Core Foundation -> CFRunLoopRef

NSRunLoopCFRunLoopRef都代表着Runloop对象
NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)

相关资料

官方:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html
CFRunLoopRef开源:http://opensource.apple.com/source/CF/CF-1151.16

RunLoop与线程
  • 每条线程都有唯一的一个与之对应的RunLoop对象
  • 主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建并开启
  • RunLoop在第一次获取时创建,在线程结束时销毁
获取RunLoop对象

Foundation

  • [NSRunLoop currentRunLoop] 获取当前线程的RunLoop对象
  • [NSRunLoop mainRunLoop] 获取主线程的RunLoop对象

Core Foundation

  • CFRunLoopGetCurrent() 获取当前线程的RunLoop对象
  • CFRunLoopGetMain() 获取主线程的RunLoop对象
子线程获取RunLoop

currentRunLoop该方法本身就是懒加载,如果第一次调用时候会创建当前线程对应的RunLoop,并保存,以后调用直接获取

  • NSRunLoop *threadRunLoop = [NSRunLoop currentRunLoop];
  • [threadRunLoop run];
相关类

Core Foundation

  • CFRunLoopRef
  • CFRunLoopModeRef
  • CFRunLoopSourceRef
  • CFRunLoopTimerRef
  • CFRunLoopObserverRef
CFRunLoopModeRef

1.CFRunLoopModeRef代表RunLoo的运行模式
2.一个RunLoop包含若干个Mode,每个Mode又包含若干个Source/Timer/Observer
3.每次RunLoop启动时,只能指定其中一个Mode,这个Mode被称作CurrentMode
4.如果需要切换Mode,只能退出RunLoop,在重新指定一个Mode进入
5.这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响

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

CFRunLoopObserverRef

CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变
可以监听的时间点有以下几个:

  • kCFRunLoopEntry 即将进入Loop
  • kCFRunLoopBeforeTimers 即将处理Timer
  • kCFRunLoopBeforeSource 即将处理Source
  • kCFRunLoopBeforeWaiting 即将进入休眠
  • kCFRunLoopAfterWaiting 刚从休眠中唤醒
  • kCFRunLoopExit 即将退出Loop
上一篇下一篇

猜你喜欢

热点阅读