iOS NSTimer定时器
NSTimer是一个定时器,能够在每个确定时间间隔里发送信息给指定对象。
这篇文章主要解决下面几个问题:
1、 NSTime创建和RunLoop
2、 NSTimer的销毁事件
3、 NSTimer需要注意的地方
一、注意
NSTimer应该是weak
因为只要创建一个NSTimer对象, 该对象就会被主线程强引用。
@property (weak, nonatomic) NSTimer *timer;
二、创建一个NSTimer定时器
- (void)viewDidLoad {
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(actionTimer:) userInfo:nil repeats:YES];
}
- (void)actionTimer:(NSTimer *)timer{
}
// 参数说明:
scheduledTimerWithTimeInterval: 创建一个定时器, 并且立即可是计时
TimeInterval: 间隔时间
target: 调用谁的方法
selector: 调用什么方法
userInfo: 需要传递什么参数
repeats: 是否重复
NSTimer默认运行在default mode下,default mode几乎包括所有输入源(除NSConnection) NSDefaultRunLoopMode模式。
actionTimer方法会每隔1s中被调用一次。NSTimer使用起来是不是非常简单。这是NSTimer比较初级的应用。
当主界面被滑动时NSTimer失效了
主界面被滑动是什么意思呢?就是说主界面有UITableView或者UIScrollView,滑动UITableView或者UIScrollView。这个时候NSTimer失效了。
解决滑动失效的方案
修改NSTimer的run loop 达到进行页面其他操作时,定时器不会受其影响
解决方法就是将其加入到UITrackingRunLoopMode模式或NSRunLoopCommonModes模式中。即
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
或者
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]
NSRunLoopCommonModes:是一个模式集合,当绑定一个事件源到这个模式集合的时候就相当于绑定到了集合内的每一个模式。
三、NSTimer定时器的销毁
关闭定时器调用 invalidate方法。
1、NSTimer是一次性的, 只要invalidate之后就不能使用了
2、只要调用invalidate方法, 系统就会将NSTimer从主线程移除, 并且销毁NSTimer对象。文中之前提到了weak属性的声明,注意看下!
[self.timer invalidate];
在 invalidate 方法的文档里还有这这样一段话:
You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.
NSTimer 在哪个线程创建就要在哪个线程停止,否则会导致资源不能被正确的释放。看起来各种坑还不少。