RunLoop表面意思运行循环,内部是由do-while循环实现。作用保证程序的持续运行,处理app的各种事件(滑动、定时器、selector等)、节省CPU资源。
->如果没有RunLoop,以main函数入口为例:
int main(int argc, char * argv[]) {
NSLog(@"执行"); // 程序开始
return 0; // 程序结束
}
程序不能持续执行,执行完代码后程序关闭。
->如果有RunLoop,以main函数入口函数为例:
int main(int argc, char * argv[]) {
do {
NSLog(@"执行"); // 程序开始
} while (1);
return 0; // 程序结束
}
相当于程序内部有一个死循环,保证程序运行不会中断。
iOS APP的main函数:
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
在UIApplicationMain函数内部启动了一个RunLoop,所以UIapplicationMain函数就一直没有返回,保持了程序的持续运行,默认启动的RunLoop是跟主线程相关联的,主要处理与主线程相关的事件。
RunLoop对象:
RunLoop对象在iOS中有两套API来访问和使用,在Foundation框架下NSRunLoop(OC语言)和Core Foundation框架下CFRunLoopRef(C语言),NSRunLoop是基于CFRunLoopRef。
RunLoop与线程:
->每条线程都有唯一的一个与之对应的RunLoop对象。
->主线程的RunLoop随着程序已经创建好,但是子线程的RunLoop需要手动创建。
->获得主线程的RunLoop的方法[NSRunLoop mainRunLoop]。
->创建子线程的RunLoop的方法是[NSRunLoop currentRunLoop],iOS不允许创建RunLoop,只提供了上述两种获得RunLoop的方法。
RunLoop相关类:
->CFRunLoopModeRef
(1)CFRunLoopModeRef代表了RunLoop的运行模式。
(2)一个RunLoop可以包含若干个Mode,每个Mode包含若干个Source/Timer/Observer
(3)每次启动RunLoop,只能指定其中的一个Mode,这个Mode被称为currentMode
(4)如果需要切换Mode,需要退出RunLoop,再重新指定一个Mode进入,这样可以分离不同组的Source/Timer/Observer,让其互不影响
(5)CFRunLoopModeRef类型,系统默认5个Mode
(a)KCFRunLoopDefaultMode:APP的默认Mode,通常主线程是在该Mode下运行
(b)UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时,不受其他Mode影响
(c)UIInitializationRunLoopMode:在刚启动时APP进入的第一个Mode,启动完成后就不再使用
(d)GSEventReceiveRunLoopMode:接受系统事件的内部Mode,通常情况下不用(忽略)
(e)KCFRunLoopCommonModes:占位用得Mode,不是真正的Mode
Mode与NSTimer与UIScrollView滚动情况:点击打开链接
->CFRunLoopSourceRef
->CFRunLoopTimerRef
CFRunLoopTimerRef是基于时间的触发器
->CFRunLoopObserverRef
要是没有这几个类,RunLoop不会循环。