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。
网友评论