1、常规使用
- (NSTimer *)heartTimer {
if (!_heartTimer) {
// scheduledTimer创建的定时器,默认添加到当前当前RunLoop的NSDefaultRunLoopMode模式下
_heartTimer = [NSTimer scheduledTimerWithTimeInterval:3
target:self
selector:@selector(heartTask)
userInfo:nil
repeats:YES];
// 修改模式
[[NSRunLoop currentRunLoop] addTimer:_heartTimer forMode:NSRunLoopCommonModes];
}
return _heartTimer;
}
- (void)heartTask {
}
- (void)restartTimer {
[self.heartTimer setFireDate:[NSDate distantPast]];
}
- (void)pauseTimer {
[self.heartTimer setFireDate:[NSDate distantFuture]];
}
- (void)dealloc {
[self.timer invalidate];
self.timer = nil;
}
2、子线程定时器的创建
- 在子线程创建定时器时,需要手动开启子线程的运行循环。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 在子线程创建定时器
/*
scheduled 或 timer 方式创建
*/
self.timer = [NSTimer timerWithTimeInterval:1.0
target:self
selector:@selector(updateTimer:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
// 启动子线程的运行循环
/*
这句代码就是一个死循环!如果不停止运行循环,不会执行添加到此句之后的任何代码
*/
CFRunLoopRun();
// 停止子线程运行循环之前,不会执行添加到此处的任何代码
});
// 定时器执行操作方法
- (void)updateTimer {
static int num = 0;
num++;
// 满足条件后,停止当前的运行循环
if (num == 8) {
// 停止当前的运行循环
/*
一旦停止了运行循环,后续代码能够执行,执行完毕后,线程被自动销毁
*/
CFRunLoopStop(CFRunLoopGetCurrent());
}
}
3、API说明
@interface NSTimer : NSObject
/**
* @brief 创建一个NSTimer对象,可以自定义执行方法及时间间隔,不会主动加入runloop中
*
* @param ti 时间间隔
* @param invocation 执行方法的NSInvocation对象
* @param yesOrNo 是否需要重复执行
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法返回的定时器不会自动添加到Runloop中,需要手动添加到Runloop
* 举例:在某个视图的生命周期内需要定时执行某个处理方法,可以使用此方法创建一个定时器
*/
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
/**
* @brief 创建一个NSTimer对象,可以自定义执行方法及时间间隔,会自动加入runloop中
*
* @param ti 时间间隔
* @param invocation 执行方法的NSInvocation对象
* @param yesOrNo 是否需要重复执行
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器会自动添加进当前的Runloop中进行调度
* 举例:在某个视图的生命周期内需要定时执行某个更新操作,可以使用此方法创建一个定时器
*/
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
/**
* @brief 创建一个NSTimer对象,可以自定义目标及执行方法、时间间隔,不会主动加入runloop中
*
* @param ti 时间间隔
* @param aTarget 执行方法的对象
* @param aSelector 执行方法的方法名
* @param userInfo 自定义的参数
* @param yesOrNo 是否需要重复执行
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器不会自动添加到当前的Runloop中,需要手动添加到Runloop
* 举例:在某个视图的生命周期内需要根据特定的时间间隔,定时刷新某个页面状态,可以使用此方法创建一个定时器
*/
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
/**
* @brief 创建一个NSTimer对象,可以自定义目标及执行方法、时间间隔,会自动加入runloop中
*
* @param ti 时间间隔
* @param aTarget 执行方法的对象
* @param aSelector 执行方法的方法名
* @param userInfo 自定义的参数
* @param yesOrNo 是否需要重复执行
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器会自动添加进当前的Runloop中进行调度
* 举例:在某个视图的生命周期内需要根据特定的时间间隔,自动进行更新操作,可以使用此方法创建一个定时器
*/
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
/**
* @brief 创建一个NSTimer对象,可以自定义时间间隔及执行代码块,不会主动加入runloop中
*
* @param interval 时间间隔
* @param repeats 是否需要重复执行
* @param block 执行代码块
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器不会自动添加到当前的Runloop中,需要手动添加到Runloop
* 举例:在某个页面需要异步加载网络数据,并且每隔一段时间需要手动刷新数据,可以使用此方法创建一个定时器
*/
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
/**
* @brief 创建一个NSTimer对象,可以自定义时间间隔及执行代码块,会自动加入runloop中
*
* @param interval 时间间隔
* @param repeats 是否需要重复执行
* @param block 执行代码块
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器会自动添加进当前的Runloop中进行调度
* 举例:在某个页面需要进行自动更新操作,每隔一段时间自动执行某个方法,可以使用此方法创建一个定时器
*/
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
/**
* @brief 创建一个NSTimer对象,可以自定义执行时间、时间间隔及执行代码块,不会主动加入runloop中
*
* @param date 初始执行时间
* @param interval 时间间隔
* @param repeats 是否需要重复执行
* @param block 执行代码块
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器不会自动添加到当前的Runloop中,需要手动添加到Runloop
* 举例:在某个视图的生命周期内需要定时执行某一操作,可以使用此方法创建一个定时器,如直播倒计时、游戏倒计时等
*/
- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
/**
* @brief 创建一个NSTimer对象,可以自定义执行时间、时间间隔及执行方法名,会自动加入runloop中
*
* @param date 初始执行时间
* @param ti 时间间隔
* @param t 执行方法的对象
* @param s 执行方法的方法名
* @param ui 自定义的参数
* @param rep 是否需要重复执行
*
* @return 返回创建的NSTimer对象
*
* @discussion 这个方法创建的定时器会自动添加进当前的Runloop中进行调度
* 举例:多场景下需要执行一个相同的逻辑处理方法,不同的场景需要在不同的时间执行,可以使用此方法创建一个定时器,如各种定时任务、页面重复刷新等
*/
- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep NS_DESIGNATED_INITIALIZER;
/**
* @brief 立即执行一次定时器的方法
*
* @discussion 举例:在某次用户操作后需要立即执行某个方法时,可以手动调用此方法。
*/
- (void)fire;
/** 定时器开始执行时间 */
@property(copy) NSDate *fireDate;
/** 定时器循环执行的时间间隔 */
@property(readonly) NSTimeInterval timeInterval;
/** 系统允许的额外时间间隔,用于调整定时器执行时间误差(API_AVAILABLE) */
@property NSTimeInterval tolerance API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
/**
* @brief 停止 NSTimer,防止再次触发计时器的事件
*
* 这个方法通常用于停止重复执行某个事件的计时器,可避免计时器被错误地执行多次。
* 例如,你正在开发一个游戏中的计时器,希望每1秒钟更新一次分数。在游戏结束后,你需要调用此方法,停止计时器,以免计时器在此后持续更新分数。
*/
- (void)invalidate;
/** 定时器是否有效 */
@property(readonly, getter=isValid) BOOL valid;
/** 用户信息,可选类型 */
@property(nullable, readonly, retain) id userInfo;
@end