iOS development run loop timer (3)

Turn on timer in main thread

1. Method 1:

//This method is automatically added to runloop internally, and the running mode is set as default (there are five running modes mentioned in the previous article)
    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];

2. Method 2

//1. Create timer
   NSTimer *timer =  [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    
    //2. Add timer to runloop, and specify that the running mode of runloop is NSDefaultRunLoopMode
    /*
     First parameter: timer
     The second parameter: running mode of runloop
     */
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

3. Problem: we can turn on a timer through the above two methods, but there are some problems in some cases. Put a tableview in a controller, and turn on a timer as described above. You will find that when scrolling the tableview, the timer does not execute the corresponding method. Why? This is because there can only be one operation mode in the operation cycle at the same time. When we are sliding tableview, the operation mode of the operation cycle is uitracking runloopmode. When we add the timer to the default mode, the timer fails when we are sliding tableview.
Solution: there is a running mode, which is kcfrnloopcommonmodes. This is an occupation and label mode. How to understand it? You can think of it as NSRunLoopCommonModes = NSDefaultRunLoopMode + UITrackingRunLoopMode. In fact, both NSDefaultRunLoopMode and uitracking runloopmode are labeled with kcfrnloop commonmodes. When you add the timer to kcfrnloopcommonmodes mode, it will execute regardless of whether the current running mode is in NSDefaultRunLoopMode mode or uitracking runloopmode.

3. Timer in GCD
Paste the code of a teacher directly, and it's very good

#import "ViewController.h"

@interface ViewController ()
/** Notes */
@property (nonatomic, strong) dispatch_source_t timer;
@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%s",__func__);
    
    
    //1. Create timer in GCD
    /*
     First parameter: the type of source dispatch ﹣ source ﹣ type ﹣ timer means timer
     Second parameter: description information, thread ID
     Third parameter: more detailed description
     The fourth parameter: queue, which determines which thread the tasks in GCD timer are executed in
     */
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    
    //2. Set timer (start time, interval time, accuracy)
    /*
     First parameter: timer object
     Second parameter: start time, dispatch "time" now
     The third parameter: the time unit in interval time 2.0 GCD is nanosecond
     Fourth parameter: absolute accuracy 0
     */
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
    
    //3. Set tasks performed by timer
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"GCD---%@",[NSThread currentThread]);
    });
    
    //4. Start execution
    dispatch_resume(timer);
    
    self.timer = timer;
}
@end

Posted on Sat, 02 May 2020 18:40:45 -0700 by jeev