Run Loop
link 死循环
Why we need this
- 保持程序持续运行
- 处理各种事件(触摸,定时器,Selector)
- 节省CPU,提高性能(该做事做事,该休息休息)
- 如果没有run loop 程序会立刻退出
int main(int argh, char* argv[] { @autoreleasepool { return UIApplicationMain(argh, argue, nil, NSStringFromClass([AppDelegate class])); } }
OC: NSRunLoop C: CFRunLoop (coreFundation)
RunLoop && Thread
- 每条线程都有位移一个Runloop对象一一对应, 主线程自动创建,子线程要手动创建,结束时销毁
- 内部实现,传入线程参数,如果不在字典里,则创建(懒加载)。用字典存线程和runloop对象,
//获取runloop对象
[NSRunLoop mainLoop];
[NSRunLoop currentRunLoop];
RunLoop Mode
- Runloop中可能存在一个或多个Mode, 但启动后只能选择一种Mode。
- Mode里面至少有一个timer或source.
- Mode种类:default, Tracking, Common(占位用的,支持前两种)/Source/Observe
//获得mode
[NSRunLoop currentRunLoop].currentMode
添加定时器到RunLoop,并指定mode。
NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 xxx:@selector xxRepeated:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultMode];
ISSUE 两个scroll 滚动一个另一个不工作
原因是: scroll的时候会切换到tracking模式。导致其他模式不工作。可切换上面的defaultmode为trackingmode,那么只有scroll的时候才工作。要想任何时候都工作,要改为commonMode。 定时器schedule与timerWithTimeInterval不同,schedule会自动加入到runloop中并且设置mode为default.
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(xx) repeats:YES];
如果在子线程开启上面的timer,不会执行。因为没有runloop(子线程runloop要手动创建),也要手动开启。
- (void) run {
NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(xx) repeats:YES];
[currentRunloop run];
}
GCD定时器
- dispatch source。 不受RunLoop任何模式影响
RunLoop的执行

Runloop应用
- NSTimer
- ImageView 显示GIF
- PerformSelector
- 常驻线程
- @autoreleasepool { }