理解RunLoop
一、什么是RunLoop?
从字面意思上来看,RunLoop就是运行循环,跑圈的意思。
我们都知道,一般来说一个线程执行一次任务之后便会退出,在iOS中,如果主线程只执行一次便退出的话也就意味着程序的停止。那么它是怎样做到让主线程保持不死,让程序一直运行的呢?答案就是RunLoop了。
打个比方:
如果没有RunLoop,程序在第三行后便结束了。
所以,RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行上面 Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 "接受消息->等待->处理" 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。
二、main函数中的RunLoop
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
UIApplicationMain函数内部就启动了一个RunLoop,所以UIApplicationMain一直没有返回,保持了程序的一直运行,这个默认启动的RunLoop是和主线程相关联的
三、RunLoop与线程
1.每条线程都有唯一的一个与之对应的RunLoop对象,实现内部是一个全局的字典,key->线程名 value->runloop
2.主线程的RunLoop已经自动创建好了,子线程的RunLoop需要主动创建
3.RunLoop在第一次获取时创建,在线程结束时销毁
四、RunLoop相关类
Core Foundation中关于RunLoop的5个类
CFRunLoopRef
CFRunLoopSourceRef
CFRunLoopTimerRef
Custom Input Sources
Cocoa Perform Selector Sources
按照函数调用栈,Source的分类
Source0:非基于Port的
Source1:基于Port的,通过内核和其他线程通信,接收、分发系统事件
d.CFRunLoopObserverRef
五、RunLoop应用
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
1.调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode
2.定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
3.标记为common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode
4.runloop Mode里如果没有timer/source/observer 不会开启成功