iOS开发中NSTimeInterval的使用方法及注意事项详解实例介绍
NSTimeInterval是一个基本数据类型,用于表示时间间隔,以秒为单位。在Objective - C中,它实际上是一个double类型,可以存储小数点后的时间值,精确到毫秒级别。
使用方法
创建计时器
以下是使用NSTimeInterval创建计时器的示例代码:
// 创建一个计时器,时间间隔为1秒
NSTimeInterval timeInterval = 1.0;
NSTimer timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(timerFireMethod:) userInfo:nil repeats:YES];
在上述代码中,使用NSTimer类创建了一个计时器,指定时间间隔为1秒,然后调用scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:方法来启动计时器。
计算两个时间点之间的时间间隔
示例代码如下:
// 定义两个时间点
NSDate startDate = [NSDate date]; // 获取当前时间
NSDate endDate = [NSDate dateWithTimeIntervalSinceNow:60]; // 当前时间往后推迟60秒
// 计算时间间隔
NSTimeInterval timeInterval = [endDate timeIntervalSinceDate:startDate];
NSLog(@"时间间隔:%f秒", timeInterval);
此代码先获取当前时间和往后推迟60秒的时间点,再使用timeIntervalSinceDate:方法计算两个时间点之间的时间间隔,并将其打印出来。
NSTimer的其他创建方式
NSTimer有多种创建方式,以下是部分方法:
// 1. + scheduledTimerWithTimeInterval: invocation: repeats:
+ (NSTimer )scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation )invocation repeats:(BOOL)yesOrNo;
// 2. + timerWithTimeInterval: invocation: repeats:
+ (NSTimer )timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation )invocation repeats:(BOOL)yesOrNo;
// 3. + timerWithTimeInterval: target:selector: userInfo:repeats:
+ (NSTimer )timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
// 4. - initWithFireDate: interval: target: selector: userInfo: repeats:
- (id)initWithFireDate:(NSDate )date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(id)ui repeats:(BOOL)rep;
需要注意的是,使用timerWithTimeInterval创建出来的对象如果不用addTimer: forMode方法手动加入主循环池中,将不会循环执行,并且如果不手动调用fire,则定时器不会启动;而scheduledTimerWithTimeInterval方法不需要手动调用fire,会自动执行,并且自动加入主循环池;init方法需要手动加入循环池,它会在设定的启动时间启动。
注意事项
精度问题
NSTimeInterval虽然能精确到毫秒级别,但在实际应用中,由于系统调度等原因,可能无法保证绝对的时间精度。例如在使用NSTimer时,它并不完全精准,可以通过设置@property NSTimeInterval tolerance;(iOS 7.0之后新增的属性)来设置误差范围。
内存释放问题
在使用NSTimer时,如果启动了一个定时器,在某个界面释放前,仅将这个定时器停止,甚至置为nil,都不能使这个界面释放,因为系统的循环池中还保有这个对象。需要使用(timer invalidate)方法将定时器从循环池中移除。
线程问题
NSTimer依赖于运行循环(RunLoop),如果运行循环的模式不匹配或者运行循环被阻塞,可能会导致定时器无法正常触发。所以在使用定时器时,要确保其所在的运行循环处于合适的模式且未被阻塞。