美文网首页
iOS中的Runroop

iOS中的Runroop

作者: Frankkkkk | 来源:发表于2019-08-19 11:09 被阅读0次

一、作用

  • 使程序一直运行并接收用户的输入(主要作用)
  • 决定程序在何时处理哪些事件
  • 调用解耦(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;
}

四、总结:

  • 要将计时器的操作放到子线程执行,不然会干扰主线程造成卡顿!
  • 子线程的运行循环是默认不工作的,当计时器的操作放到子线程后,要手动开启子线程的运行循环。
  • 当不需要计时器工作时(或控制器销毁时),要手动停止计时器。

相关文章

网友评论

      本文标题:iOS中的Runroop

      本文链接:https://www.haomeiwen.com/subject/gbnjsctx.html