一、作用
- 使程序一直运行并接收用户的输入(主要作用)
- 决定程序在何时处理哪些事件
- 调用解耦(Message Queue)
- 节省CPU时间(当程序启动后,什么都没有执行的话,就不用让CPU来消耗资源来执行,直接进入睡眠状态)
二、模式
- RunLoop 在同一段时间只能且必须在一种特定的模式下运行
- 如果要更换 Mode,必须先停止当前的 Loop,然后再重新启动 Loop
-
NSDefaultRunLoopMode
: :默认状态、空闲状态 -
UITrackingRunLoopMode
:滚动模式 -
NSRunLoopCommonModes
:组合模式,包含上面两种模式
三、实际应用
以计时器为例:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimer) object:nil];
[self.thread start];
}
- (void)startTimer {
@autoreleasepool {
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(fire) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
_timerRf = CFRunLoopGetCurrent();
CFRunLoopRun();
NSLog(@"计时器结束");
}
}
- (void)fire {
// 模拟延时 No run loop processing occurs while the thread is blocked.
// 线程休眠的时候,run loop 不响应任何事件,开发中不要使用
// [NSThread sleepForTimeInterval:1.0];
// for (int i = 0; i < 1000 * 1000; ++i) {
// [NSString stringWithFormat:@"hello - %d", i];
// }
static int num = 0;
NSLog(@"%d %@", num++, [NSThread currentThread]);
// 满足某一个条件时,停止运行循环
if (num == 3) {
NSLog(@"停止计时器");
CFRunLoopStop(CFRunLoopGetCurrent());
}
}
- (IBAction)stop {
if (_timerRf == NULL) {
return;
}
CFRunLoopStop(_timerRf);
_timerRf = NULL;
}
四、总结:
- 要将计时器的操作放到子线程执行,不然会干扰主线程造成卡顿!
- 子线程的运行循环是默认不工作的,当计时器的操作放到子线程后,要手动开启子线程的运行循环。
- 当不需要计时器工作时(或控制器销毁时),要手动停止计时器。
网友评论