NSTimer总结

一:分类封装
+ (NSTimer *)BN_timeInterval:(NSTimeInterval)interval
                       block:(void(^)(NSTimer *timer))block
                     repeats:(BOOL)repeats{

    return [self scheduledTimerWithTimeInterval:interval
                                         target:self
                                       selector:@selector(p_handleInvoke:)
                                       userInfo:[block copy]
                                        repeats:repeats];
}

+ (void)p_handleInvoke:(NSTimer *)timer {
    void(^block)(NSTimer *timer) = timer.userInfo;
    if(block) {
        block(timer);
    }
}

/**
 定时器暂停/继续
 */
+ (void)pauseTimer:(NSTimer *)timer isPause:(BOOL)isPause{
//    暂停:触发时间设置在未来,既很久之后,这样定时器自动进入等待触发的状态.
//    继续:触发时间设置在现在/获取,这样定时器自动进入马上进入工作状态.
    timer.fireDate = isPause == false ? NSDate.distantFuture : NSDate.distantPast;
}

+ (void)stopTimer:(NSTimer *)timer{
    [timer invalidate];
    timer = nil;
    NSLog(@"timer stop!!!");
}

二.工具类封装
void dispatchTimer(id target, double timeInterval,void (^handler)(dispatch_source_t timer)){
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
    dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), (uint64_t)(timeInterval *NSEC_PER_SEC), 0);
    // 设置回调
    __weak __typeof(target) weaktarget = target;
    dispatch_source_set_event_handler(timer, ^{
        if (!weaktarget)  {
            dispatch_source_cancel(timer);
            NSLog(@"dispatch_source_cancel!!!");
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (handler) handler(timer);
            });
        }
    });
    // 启动定时器
    dispatch_resume(timer);
}

示例:
@property (nonatomic, strong) NSTimer * timer;

-(void)dealloc{
    [NSTimer stopTimer:_timer];
    
}

- (void)viewDidLoad {
    [super viewDidLoad];

  __block NSInteger i = 0;
    _timer = [NSTimer BN_timeInterval:1 block:^(NSTimer *timer) {
        i++;
        DDLog(@"__%@",@(i));
    } repeats:YES];

    BN_dispatchTimer(self, 1, ^(dispatch_source_t timer) {
        i++;
        DDLog(@"%@",@(i));
    });
}

须知:
1,调用NSTimer会对调用的对象retain
2,NSTimer必须加入NSRunloop中才能正确执行
3,NSTimer并不是一个实时的系统(不准确)
4.NSRunLoopCommonModes这是一个伪模式,是run loop mode的集合,此模式意味着在Common Modes中包含的所有模式下都可以处理。
在Cocoa应用程序中,默认情况下Common Modes包含default modes,modal modes,event Tracking modes.
可使用CFRunLoopAddCommonMode方法想Common Modes中添加自定义modes。

你可能感兴趣的:(NSTimer总结)