@chenbinghua
2015-09-12T10:33:15.000000Z
字数 2187
阅读 1563
iOS笔记
RunLoop要跑起来必须要由mode
CFRunLoopModeRef
代表RunLoop的运行模式
一个 RunLoop 包含若干个 Mode,每个Mode又包含若干个Source/Timer/Observer
每次RunLoop启动时,只能指定其中一个 Mode,这个Mode被称作 CurrentMode
如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入
这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响
系统默认注册了5个Mode:
NSDefaultRunLoopMode
:App的默认Mode,通常主线程是在这个Mode下运行
UITrackingRunLoopMode
:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响.
(目的是在ScrollView滚动时,使主线程只关注ScrollView滚动,使得用户操作更流畅。所以当ScrollView滚动时,主线程的NSTimer失效)
UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
NSRunLoopCommonModes
: 这是一个占位用的Mode,不是一种真正的Mode
CFRunLoopTimerRef是基于时间的触发器
CFRunLoopTimerRef基本上说的就是NSTimer,它受RunLoop的Mode影响
GCD的定时器不受RunLoop的Mode影响
拖一个UITextView
到storyboard,UITextView
继承自UIScrollView
// ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// scheduledTimerWithTimeInterval方法等于一下两句,将NSTimer添加到NSDefaultRunLoopMode
// [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
}
- (void)run{
NSLog(@"____run");
}
@end
程序运行,每隔两秒就会打印一次,当拖动UITextView
时,定时器失效,不会打印。原因是拖动时,主线程的RunLoop切换到UITrackingRunLoopMode
模式,而定时器在NSDefaultRunLoopMode
模式。
解决办法:将定时器添加到标记为common modes的模式下
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
// 定时器会跑在标记为common modes的模式下
// 标记为common modes的模式:UITrackingRunLoopMode和kCFRunLoopDefaultMode
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
应用:当有控件滚动时,才开始做动作的需求时,可以把做动作的方法添加到NSDefaultRunLoopMode
模式。
CFRunLoopSourceRef是事件源(输入源)
按照官方文档,Source的分类
按照函数调用栈,Source的分类
Source0:非基于Port的
Source1:基于Port的,通过内核和其他线程通信
CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变
可以监听的时间点有以下几个