以前学到Runloop时,总感觉迷迷糊糊。刚好过年在家也没事,就找了些关于runloop的资料。
先整理下MJ老师对于Runloop的讲解:
字面意思:运行循环、跑圈
基本作用:
保持程序的持续运行,
处理
App
中的各种事件(比如触摸事件、定时器事件、
Selector
事件),
节省
CPU
资源,提高程序性能:该做事时做事,该休息时休息等等
举个例子,倘若没有runloop,
int main(int argc, char* argv[]){
NSLog(@"executemain function");
return 0;
}
程序到了return直接结束了
加入runloop后
int main(int argc, char * argv[]) {
BOOL running = YES;
do {
//do something...
} while (running);
return 0;
}
由于main函数里面启动了个RunLoop,所以程序并不会马上退出,保持持续运行状态.
在程序的main函数中
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
UIApplicationMain
函数内部就启动了一个
RunLoop,
所以
UIApplicationMain
函数一直没有返回,保持了程序的持续运行。而
这个默认启动的
RunLoop
是跟主线程相关联。
iOS中有两套API来访问和使用Runloop
Foundation-->>NSRunLoop
Core Foundation-->>CFRunLoopRef
NSRunLoop
和
CFRunLoopRef
都代表着
RunLoop
对象
NSRunLoop
是基于
CFRunLoopRef
的一层
OC
包装,所以要了解
RunLoop
内部结构,需要多研究
CFRunLoopRef
层面的
API
(
Core
Foundation
层面)
RunLoop与线程
1.每条线程都有唯一的一个与之对应的
RunLoop
对象
2.
主线程的
RunLoop
已经自动创建好了,子线程的
RunLoop
需要主动创建
3.
RunLoop
在第一次获取时创建,在线程结束时销毁
获得RunLoop对象
·Foundation
[NSRunLoopcurrentRunLoop];// 获得当前线程的RunLoop对象
[NSRunLoopmainRunLoop];// 获得主线程的RunLoop对象
·Core
Foundation
CFRunLoopGetCurrent();// 获得当前线程的RunLoop对象
CFRunLoopGetMain();// 获得主线程的RunLoop对象
RunLoop相关类
-
Core
Foundation
中关于
RunLoop
的
5
个类
·
CFRunLoopRef
·
CFRunLoopModeRef
·
CFRunLoopSourceRef
·
CFRunLoopTimerRef
·
CFRunLoopObserverRef
-
CFRunLoopModeRef
代表
RunLoop
的运行模式
·
一个
RunLoop
包含若干个
Mode
,
每个
Mode
又包含若干个
Source/Timer/Observer
·
每次
RunLoop
启动时
,只能指定其中一个
Mode
,这个
Mode
被称作
CurrentMode
·
如果需要切换
Mode
,只能退出
Loop
,再重新指定一个
Mode
进入
·
这样做主要是为了分隔开不同组的
Source/Timer/Observer
,让其互不影响
-系统默认注册了
5
个
Mode:
·
kCFRunLoopDefaultMode
:
App
的默认
Mode
,通常主线程是在这个
Mode
下运行
·
UITrackingRunLoopMode
:界面跟踪 Mode,用于 ScrollView追踪触摸滑动,保证界面滑动时不受其他Mode 影响
·UIInitializationRunLoopMode
:
在刚启动
App
时第进入的第一个
Mode
,启动完成后就不再使用
·GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
·kCFRunLoopCommonModes: 这是一个占位用的Mode,不是一种真正的Mode
-CFRunLoopSourceRef
是事件源(输入源)
-以前的分法
·Port-BasedSources
·Custom InputSources
·Cocoa PerformSelector Sources
-现在的分法
·Source0
:非基于
Port
的
·Source1
:基于
Port
的
-CFRunLoopTimerRef
是基于时间的触发器,基本上说的就是NSTimer。
-CFRunLoopObserverRef
是
观察者,能够监听
RunLoop
的状态改变。可以监听的时间点有以下几个:
RunLoop处理逻辑-官方版
Runloop处理逻辑-网友整理版
-Runloop应用
·NSTimer
·ImageView
显示
·PerformSelector
·常驻线程
·自动释放池
家人喊着吃饭,先到这里,晚上再整理。