RunLoop基本使用
2016-08-20 本文已影响44人
音吹
基本作用
- 保持程序的持续运行
- 处理App中的各种事件
- 节省CPU资源,提高程序性能.
入口
iOS中有Foundation和Core Foundation来使用RunLoop
Foundation:NSRunLoop
Core Foundation:CFRunLoopRef
概念
- 每条线程都有唯一相对应的RunLoop对象
- 主线程的RunLoop已经自动创建,子线程的RunLoop需要主动创建
- RunLoop在第一次获取时创建,在线程结束时销毁
使用
//获取当前线程对应的RunLoop
NSRunLoop * currentRunLoop = [NSRunLoop currentRunLoop];
//获取当前线程对应的RunLoop
CFRunLoopRef runLoop = CFRunLoopGetCurrent();
//之间的关系
runLoop = currentRunLoop.getCFRunLoop;
RunLoop相关类
Core Foundation中:
-
CFRunLoopRef
-
CFRunLoopModeRef:运行模式
-
CFRunLoopSourceRef:事件(输入)源
-
CFRunLoopTimerRef:定时器
-
CFRunLoopObserverRef
-
1.一个RunLoop包含了若干个Mode,每个Mode又包含了若干个Source/Timer/Observer
-
2.每次RunLoop启动时,只能指定其中一个Mode,这个Mode称为CurrentMode
-
3.如果需要切换Mode,只能退出Loop.再重新指定一个Mode进入
-
4.这样做主要是为了分隔开来不同组的Source/Timer/Observer,让其互不影响
******系统默认注册了5个Mode
主要用的两个:
kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时不受其他Mode影响
CFRunLoopTimerRef
- 基于时间的触发器,基本上是NSTimer,受RunLoop的Mode影响
- GCD的定时器不受RunLoop的Mode的影响
CFRunLoopSourceRef
- 事件源(输入源)
- 用户主动触发是source0
CFRunLoopObserverRef
- 观察者,监听RunLoop的状态改变
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0), //即将进入Loop
kCFRunLoopBeforeTimers = (1UL << 1), //即将处理Timer
kCFRunLoopBeforeSources = (1UL << 2), //即将处理Source
kCFRunLoopBeforeWaiting = (1UL << 5), //即将进入休眠
kCFRunLoopAfterWaiting = (1UL << 6), //刚从休眠中唤醒
kCFRunLoopExit = (1UL << 7), //即将退出Loop
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
- 基本使用
//创建Observer
/**
*
*
* @param kCFAllocatorDefault 默认分配内存空间
* @param kCFRunLoopAllActivities 监听什么状态,这个是监听所有状态
* @param YES 是否持续监听
* @param 0 优先级
* @param observer 回调
* @param activity 回调
*
* @return return value description
*/
CFRunLoopObserverRef observer =
CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"---RunLoop状态发生改变----%zd",activity);
});
//添加观察者,监听RunLoop的状态
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
//释放Observer
CFRelease(observer);
给当前RunLoop添加source
[[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];