一:CFRunLoopModeRef

  1. CFRunLoopModeRef带表RunLoop的运行模式

  2. 一个Runloop可以有若干个mode,每个mode又包含若干个sourse,timer,observer

     

    

 3. 每当RunLoop启动时,只能指定其中一个mode,这个Mode被称为CurrentMode

    [[NSRunLoop currentRunLoop].currentMode

 如果需要切换Mode,只能退出Runloop,再重新指定一个Mode来运行。这样做的目的就是为了分割不同组的Source/Timer/Observer.

 4.两个常用的Mode

  4.1 kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode中运行的。

  4.2 UITrackingRunLoopMode:界面跟踪Mode,用于ScrollView追踪触摸滑动,保证界面滑动时,不受其他Mode影响。

 

二:添加定时器到不同Mode中的区别

  1.当程序中有scrollView等滚动时,RunLoop的模式切换为UITrackingRunLoopMode,如果将定时器添加到NSDefaultRunloopMode中,滚动比如textView定时器将不工作。如以下代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSTimer *timer =   [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES ];
    // 将定时器添加到当前主线程的RunLoop的默认Mode下
    // 可以发现,当textView滚动时,不会打印
    [[NSRunLoop currentRunLoop ] addTimer:timer forMode:NSDefaultRunLoopMode];
}
- (void)run{
    NSLog(@"%s",__func__);
}

  2.如果将定时器加入的Mode设为NSRunLoopCommonModes时,则当RunLoop为NSDefaultRunloopMode与UITrackingRunLoopMode时都将工作。

  

    [super viewDidLoad];
    NSTimer *timer =   [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES ];
    // 将定时器添加到当前主线程的RunLoop的默认Mode下
    // 如果改为forMode:NSRunLoopCommonModes,则定时器继续工作
    [[NSRunLoop currentRunLoop ] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)run{
    NSLog(@"%s",__func__);
}

  3.可以在打印RunLoop对象中发现:

  

  可以发现,NSRunLoopCommonModes其实相当于一个标记符,标记某些Mode,默认标记是DefaulMode与TrackingMode。