iOS开发中定时器的使用:
1.我们平时用到的定时器主要是这样的:
NSTimer *_timer;
if (!_timer) {
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startTimerMethod) userInfo:nil repeats:YES];
}
- (void)startTimerMethod {
}
使用这种定时器可以满足我们基本的需求,但是有时候我们会用到交互,就是在存在UITableView的界面上添加定时器,这个时候我们上下滚动TableView,定时器暂停工作,手指离开屏幕,定时器继续运行。
这是一种非常便利的定时器创建方法,在这个方法中定时器其实做了两件事:1.创建一个Timer。2.将Timer添加到当前RunLoop的NSDefaultRunLoopMode中。
2.NSTimer的另一种创建方法是:
NSTimer *_timer;
if (!_timer) {
_timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:1] interval:1 target:self selector:@selector(startTimerMethod) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
- (void)startTimerMethod {
}
用这种方法创建定时器,可以控制定时器在什么时间开始启动,这种方法必须手动把定时器添加到RunLoop里面,否则不能开始定时器。
3.NSTimer的第三种创建方法:
NSTimer *_timer;
if (!_timer) {
_timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(startTimerMethod) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
[_timer fire];
}
- (void)startTimerMethod {
}
用这种方法创建定时器,必须把定时器加入RunLoop里,并且,如果不手动fire,定时器不能立即开启。
好,那下面就说一下定时器的使用场景,暂停,开启,移除定时器。
第一种创建方法是我们平时经常使用的,但是当页面存在TableView,CollectionView,ScrollView的时候,使用第一种方法创建定时器就不好用了,这个时候可以使用第二种,第三种方法创建定时器。这个时候一定要Timer加入RunLoop里,因为视图的加载主要是在mainRunLoop,如果同事创建多个Timer,最好把定时器加到currentRunLoop里面,如果有必要可以开启子线程。如果遇到TableView,CollectionView,ScrollView的时候,就要使用NSRunLoopCommonModes Mode。
每个RunLoop运行在不同的Mode下,下面就具体说说不同Mode的适用场景。
// 默认模式,几乎包含了所有输入源(NSConnection除外),一般情况下使用此模式。
// 在拖动loop或其他user interface tracking loops时处于此种模式下,在此模式下会限制输入事件的处理。例如,当手指按住UITableView拖动时就会处于此模式。
// 这是一个伪模式其为一组run loop mode的集合,将输入源加入此模式意味着在Common Modes中包含的所有模式下都可以处理。
@property (copy) NSDate *fireDate; // 设置定时器什么时间开启启动,[NSDate distantPast]定时器马上启动,[NSDate dateWithTimeIntervalSinceNow:2]定时器两秒之后再启动。
@property (readonly) NSTimeInterval // 设置调用定时器的时间间隔。i meInterval;
@property NSTimeInterval tolerance NS_AVAILABLE(10_9, 7_0); // 因为定时器不是完全精准的,调用这个值设置误差范围。
@property (readonly, getter=isValid) BOOL valid; // 获取定时器是否有效,YES有效,NO无效
// 暂停定时器
[_timer setFireDate:[NSDate distantFuture]];
// 开启暂停的定时器
[_timer setFireDate:[NSDate distantPast]];
- (void)clearTimer {
if (_timer.valid) {
[_timer invalidate];
}
_timer = nil;
}
在官方文档中,invalidate 是唯一的方法将定时器从循环池中移除,停止后一定要把 _timer = nil; 否则还是没有释放,会造成内存泄漏。
以上是本人的理解:如有问题欢迎指正。