1.runloop的作用 :
保证程序不退出
负责事件的监听,时钟(定时器)/触摸事件/网络事件
当没有事件发生的时候,会让程序进入休眠状态
渲染屏幕上的点
2.runloop的对象
Foundation框架里面有NSRunloop,
[NSRunLoop currentRunLoop];//获取当前线程的runloop对象
[NSRunLoop mainRunLoop];//获取主线程的runloop对象
Core Foundation里面有CFRunloopRef
CFRunLoopGetCurrent();//获取主线程的runloop对象
CFRunLoopGetMain();//获取主线程的runloop对象
其中NSRunloop是基于CFRunloopRef加一层OC的封装。
3.runloop的modes
1.UIInitializationRunLoopMode,刚启动app调用的mode,完成后不在使用.
2.GSEventReceiveRunLoopMode,接受系统事件的内部mode,用不到。
3.NSDefaultRunLoopMode,默认mode,苹果建议将时钟还有网络添加到这个mode
4.UITrackingRunLoopMode,处理UI的mode,并保证在交互时不受其他mode影响
———NSRunLoopCommonModes,是一种占位mode。。。使用这个mode会在需要的时候在NSDefaultRunLoopMode跟UITrackingRunLoopMode来回占位,保证在两种mode中都运行不受影响。
4.runloop处理的事件
1.CFRunLoopSourceRef 事件输入源,
source0:用于用户主动触发事件(非系统事件)
source1:通过内核和其它线程相互发送消息,系统事件
2.CFRunLoopObserverRef ——runloop的观察者
/**
runloop的活动观察
kCFRunLoopEntry = (1UL << 0),进入runloop
kCFRunLoopBeforeTimers = (1UL << 1),处理timer前
kCFRunLoopBeforeSources = (1UL << 2),处理source前
kCFRunLoopBeforeWaiting = (1UL << 5),休眠前
kCFRunLoopAfterWaiting = (1UL << 6),休眠后
kCFRunLoopExit = (1UL << 7),退出
kCFRunLoopAllActivities = 0x0FFFFFFFU 所有事件
*/
// 创建一个监听者
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
NSLog(@"%ld",activity);
});
// 给runloop添加监听者
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopDefaultMode);
// 释放runloop
CFRelease(observer);
3.CFRunLoopTimerRef——基于时间的触发器
NSTimer * timer1 = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updataTimer) userInfo:nil repeats:YES];
使用上面方法创建timer会自动加入runloop,但是模式是默认的NSDefaultRunLoopMode(苹果建议将时钟加入此mode)。所以在于界面交互时timer会停止,故而轮播图常常需要使用下面的方法创建定时器
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updataTimer) userInfo:nil repeats:YES];//不会自动加入runloop,需要手动加入
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];//这是死循环,故而经常单独写一个子线程
CGD的定时器不受runloop影响
//创建队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//创建定时器
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//设置定时器
dispatch_time_t interval = 1.0 * NSEC_PER_SEC;//时间间隔
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, interval, 0);
//设置事件
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"%@------",[NSThread currentThread]);
});
//启动定时器
dispatch_resume(self.timer);