定時(shí)器:讓程序定時(shí)執(zhí)行某一個(gè)方法蹄殃。
用 NSTimer 封裝的定時(shí)器示例
MyTimeCounter.h 文件
#import <Foundation/Foundation.h>
@protocol MyTimeCounterDelegate <NSObject>
// 外部調(diào)用這個(gè)類需要實(shí)現(xiàn)的代理方法,用于返回當(dāng)前計(jì)時(shí)的時(shí)間
-(void)currentTime:(NSUInteger)time;
@end
// 自定義的定時(shí)器類
@interface MyTimeCounter : NSObject
@property (nonatomic, strong) id<PATimeCounterDelegate>delegate;
- (void)start;
- (void)stop;
- (void)pause;
- (void)continue;
@end
MyTimeCounter.m 文件
#import "MyTimeCounter.h"
@interface MyTimeCounter()
@property (nonatomic, assign) NSUInteger count; // 全局屬性川蒙,用于記錄當(dāng)前的秒數(shù)
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation MyTimeCounter
// 開始計(jì)時(shí)
- (void)start {
[self start]; // 重置計(jì)時(shí)器
/* 方法作用:每隔1秒執(zhí)行指定方法
*
* 參數(shù)說(shuō)明:
* TimeInterval : 執(zhí)行之前等待的時(shí)間。比如設(shè)置成 1.0清酥,就代表 1 秒后執(zhí)行方法寒匙。
* target : 需要執(zhí)行方法的對(duì)象罕偎。
* selector : 需要執(zhí)行的方法。
* userInfo : 用戶信息
* repeats : 是否需要循環(huán)
*/
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(repeatShowTime:)
userInfo:nil
repeats:YES];
}
- (void)repeatShowTime:(NSTimer *)tempTimer {
_count ++;
// 返回當(dāng)前記錄的時(shí)間
if (_delegate && [_delegate respondsToSelector:@selector(currentTime:)]) {
[_delegate currentTime:_count];
}
}
// 停止計(jì)時(shí)
- (void)stop {
// 如果已經(jīng)存在 timer 對(duì)象陌知,則釋放
if (self.timer) {
[self.timer invalidate]; // 釋放計(jì)時(shí)器
self.timer = nil;
}
_count = 0;
}
// 暫停
- (void)pause {
[self.timer setFireDate:[NSDate distantFuture]];
}
// 繼續(xù)
- (void)continue {
[self.timer setFireDate:[NSDate date]];
}
// 銷毀
- (void)dealloc {
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
}
}
@end
外部調(diào)用
#import "MyTimeCounter.h"
// 默認(rèn)倒計(jì)時(shí) 15s
static int const KCountDown = 15;
//...
@property (nonatomic, strong) MyTimeCounter *timeManager; // 倒計(jì)時(shí)管理器
//...
// Lazy loading
- (PATimeCounter *)timeManager{
if (!_timeManager) {
_timeManager = [[PATimeCounter alloc] init];
_timeManager.delegate = self;
}
return _timeManager;
}
- (void)myFunction {
[self.timeManager start]; // 開始倒計(jì)時(shí)
// ...
[self.timeManager stop]; // 結(jié)束倒計(jì)時(shí)
}
#pragma mark - MyTimeCounterDelegate
// 倒計(jì)時(shí)管理器
- (void)currentTime:(NSUInteger)time {
if (time != KCountDown) {
// 主線程更新 UI
__weak __typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.timeLabel.text = [NSString stringWithFormat:@"%d", KCountDown - time];
});
} else {
_isTimeOut = YES;
}
}
通過 GCD 實(shí)現(xiàn)的 60s 倒計(jì)時(shí)示例
// 重復(fù)執(zhí)行事件
__block int timeout = 60; // 倒計(jì)時(shí)時(shí)間
NSTimeInterval intervalInSeconds = 1.0; // 執(zhí)行時(shí)間間隔他托,1秒
// 全局隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
// 計(jì)時(shí)器
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, intervalInSeconds * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
// 執(zhí)行的事件
if (timeout <= 0) {
dispatch_source_cancel(timer);
dispatch_async(dispatch_get_main_queue(), ^{
// 主隊(duì)列執(zhí)行
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
// 主隊(duì)列執(zhí)行
});
}
timeout --;
});
dispatch_resume(timer);
開源的第三方框架
參考 GitHub:https://github.com/search?q=iOS+Countdown