RunLoop

RunLoop_第1张图片

APP启动时运行main函数,main函数里面启动了RunLoop,然后这个RunLoop一直跑圈就像do····while(YES)死循环那样,程序一直保持运行状态,时刻准备处理App的各种事件(例如触摸事件、定时器事件、Selector事件)。一条线程对应一个RunLoop对象且生死同步。NSTimer的固定频率执行方法本质上就是定时输入事件到RunLoop,PerformSelector也是产生事件输入源输入到RunLoop之中。

main函数

访问RunLoop对象

  • Foundation框架NSRunLoop类(CFRunLoopRef的OC包装)
// 获得当前线程的RunLoop对象
[NSRunLoop currentRunLoop];

// 获得主线程的RunLoop对象
[NSRunLoop mainRunLoop]; 
  • Core Foundation框架CFRunLoopRef类
// 获得当前线程的RunLoop对象
CFRunLoopGetCurrent(); 

// 获得主线程的RunLoop对象
CFRunLoopGetMain(); 

RunLoop其他类

  • RunLoop的运行模式类:CFRunLoopModeRef
一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer;
每次RunLoop启动时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode;
如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入;
这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响。

> 系统默认注册了5个Mode:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView 追踪触摸滑动,保证界面滑动时不受其Mode影响
UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode,只有把NSTimer的runloop model切换成这个模式才能够保证及时用户拖动TableView系统进入UITrackingRunLoopMode不被中断。
  • RunLoop的事件输入源类:CFRunLoopSourceRef
Port-Based             Sources
Custom Input           Sources
Cocoa Perform Selector Sources

Source0:非基于Port的
Source1:基于Port的
  • RunLoop的时间触发器类:CFRunLoopTimerRef
类似于NSTimer不断计时然后条件触发事件
  • RunLoop的观察者类:CFRunLoopObserverRef
RunLoop_第2张图片
监听RunLoop的状态改变

RunLoop处理逻辑

RunLoop_第3张图片
事件输入源
RunLoop_第4张图片
RunLoop处理逻辑
RunLoop_第5张图片
RunLoop时序

你可能感兴趣的:(RunLoop)