美文网首页
NSTimer完美封装/总结

NSTimer完美封装/总结

作者: SoaringHeart | 来源:发表于2018-05-07 17:01 被阅读43次

NSTimer完美封装/总结

声明:此文章综合博主浏览过的众多博客而成,为了彻底解决NSTimer容易出问题而公开,
不必打赏,大家免费用,随便优化
一:分类封装
+ (NSTimer *)BN_timeInterval:(NSTimeInterval)interval
                       block:(void(^)(NSTimer *timer))block
                     repeats:(BOOL)repeats{

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

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

+ (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完美封装/总结

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