iOS NSTimer定时器详解及注意事项
1. 接口
@interface NSTimer : NSObject
// 该方式默认会将定时器添加到NSRunLoop中
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
// 该方式必须手动加入到当前循环中去,必须显式加入:[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
// 创建一个定时器如果不手动触发定时器,那么定时器会过TimeInterval秒后自动执行selector
// 如果想立刻执行直接调用fire方法
// 在重复执行的定时器中调用此方法后立即触发该定时器,但不会中断其之前的执行计划;
// 在不重复执行的定时器中调用此方法,立即触发后,就会使这个定时器失效。
- (void)fire;
- (void)invalidate; // 停止定时器(永久停止)不是暂停定时器, 这个是唯一一个可以将计时器从runloop中移出的方法
@property (copy) NSDate *fireDate; //重新设置定时器开始运行的时间
@property(readonly, getter=isValid) BOOL valid; // 定时器是否正在运行中
@end
2.注意事项
1、初始化
//方式1:创建一个定时,该方式默认会将定时器添加到NSRunLoop
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(action:) userInfo:nil repeats:YES];
//方式2: 该方式必须显式手动加入到当前循环中去
NSTimer *timer = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(action:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
2、注意事项
NSTimer可以精确到50-100毫秒.
NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了.
[NSDate distantFuture];(不可达到的未来的某个时间点)
[NSDate distantPast]; (不可达到的过去的某个时间点)
NSTimer可以精确到50-100毫秒.
NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了.
[NSDate distantFuture];(不可达到的未来的某个时间点)
[NSDate distantPast]; (不可达到的过去的某个时间点)
// 永久停止定时器,一但停止将永久停止而不是暂停
[timer invalidate];
timer = nil;
3、立刻启动 暂停 继续 停止
[timer fire]; // 立刻启动
[timer invalidate]; // 停止
[timer setFireDate:[NSDate distantFuture]]; // 暂停
[timer setFireDate:[NSDate distantPast]]; // 继续
3. 示例Demo
#import <UIKit/UIKit.h>
@interface MainViewController : UIViewController {
int i;
NSTimer * timer;
}
@property (weak, nonatomic) IBOutlet UILabel *label;
// 立即开始
- (IBAction)startOnClicked:(UIButton *)sender;
// 永久停止
- (IBAction)stopOnClicked:(UIButton *)sender;
// 暂停
- (IBAction)pauseOnClicked:(UIButton *)sender;
// 继续
- (IBAction)resumeOnClicked:(UIButton *)sender;
@end
#import "MainViewController.h"
@interface MainViewController ()
@end
@implementation MainViewController
#pragma mark -
#pragma mark - View LifeCycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"NSTimer Demo";
i = 0;
timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
}
//页面将要进入前台,开启定时器
-(void)viewWillAppear:(BOOL)animated {
[timer setFireDate:[NSDate distantPast]]; //开启定时器
}
//页面消失,进入后台不显示该页面,关闭定时器
-(void)viewDidDisappear:(BOOL)animated {
[timer setFireDate:[NSDate distantFuture]]; //关闭定时器
}
#pragma mark - Actions
- (void)timerAction:(NSTimer *)timer {
i += 1;
self.label.text = [NSString stringWithFormat:@"%d", i];
NSLog(@"run : %d", i);
}
- (IBAction)startOnClicked:(UIButton *)sender {
NSLog(@"right now start ---------------");
[timer fire];
}
- (IBAction)stopOnClicked:(UIButton *)sender {
NSLog(@"game over ~~~~~~~~~~~~~~~~~~~~");
[timer invalidate];
}
- (IBAction)pauseOnClicked:(UIButton *)sender {
NSLog(@"XXXXXXXX pause XXXXXXXX");
[timer setFireDate:[NSDate distantFuture]];
}
- (IBAction)resumeOnClicked:(UIButton *)sender {
NSLog(@"resume...");
[timer setFireDate:[NSDate distantPast]];
}
@end
效果如图:
示例代码: http://download.csdn.net/detail/vbirdbest/9442976