iOS中有2套API来访问和使用RunLoop
# Foundation
NSRunLoop
# Core Foundation
CFRunLoopRef
// NSRunLoop和CFRunLoopRef都代表着RunLoop对象
// NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面)
RunLoop资料
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对象
Core Foundation中关于RunLoop的5个类
CFRunLoopRef:它自己,也就代表一个RunLoop对象
CFRunLoopModeRef :RunLoop的运行模式
一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer每次RunLoop启动时,只能指定其中一个Mode,这个Mode被称作 CurrentMode如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
UIInitializationRunLoopMode: 在刚启动 App 时进入的第一个 Mode,启动完成后就不再使用
GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
被标记为common modes模式kCFRunLoopDefaultMode UITrackingRunLoopMode两种模式
CFRunLoopSourceRef :事件源
以前的分法
Port-Based Sources
Custom Input Sources
Cocoa Perform Selector Sources
现在的分法
Source0:非基于Port的
Source1:基于Port的
CFRunLoopTimerRef :时间的触发器
CFRunLoopTimerRef是基于时间的触发器,基本上就是NSTimer
CFRunLoopObserverRef :观察者 监听CFRunLoopRef的状态改变
观察者,能够监听RunLoop状态改变。
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), //即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2), // 即将处理Sources
kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), // 即将退出Loop
};
网友评论