在iOS開發(fā)的過程中定時器的使用比較頻繁的,比較常見的場景是驗證碼的發(fā)送,或者是倒計時的展示.一般的需求我們直接使用NSTimer就能完成炊琉。但是NSTimer的坑也是比較多的,比如在UITableview的時候,需要把NSTimer添加到主循環(huán)苔咪,并且設(shè)置為NSRunLoopCommonModes锰悼。但是今天要記錄的是:GCD定時器
先直接貼代碼
File:GCDCountDown.h
@interface GCDCountDown()
@property(nonatomic,strong)dispatch_source_t timer;
+(instancetype)manager;
-(void)resume;
-(void)pause;
@end
*************************************************************************************
File:GCDCountDown.m
@implementation GCDCountDown
+(instancetype)manager{
static GCDCountDown *countDown = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (countDown == nil) {
countDown = [[GCDCountDown alloc]init];
}
});
return countDown;
}
-(instancetype)init{
self = [super init];
if (self) {
[self loadTimer];
}
return self;
}
//定時器設(shè)置
-(void)loadTimer{
if (self.timer) {
dispatch_cancel(self.timer);
self.timer = nil;
}
dispatch_queue_t queue = dispatch_get_main_queue();
//創(chuàng)建一個定時器(dispatch_source_t本質(zhì)上還是一個OC對象)
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//設(shè)置定時器的各種屬性
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0*NSEC_PER_SEC));
uint64_t interval = (uint64_t)(1.0*NSEC_PER_SEC);
dispatch_source_set_timer(self.timer, start, interval, 0);
//設(shè)置回調(diào)
__weak typeof(self) weakSelf = self;
dispatch_source_set_event_handler(self.timer, ^{
//定時器需要執(zhí)行的操作
[weakSelf timerAction];
});
//啟動定時器(默認(rèn)是暫停)
dispatch_resume(self.timer);
}
-(void)resume{
//重新加載一次定時器
[self loadTimer];
}
-(void)pause{
if (self.timer) {
dispatch_cancel(self.timer);
self.timer = nil;
}
}
@end
這是為了適配項目的需求封裝的一個簡單的定時器單例,精簡了一些業(yè)務(wù)代理团赏,不過主要的用法都貼出來了箕般。GCD定時器的定義和使用就是這么簡單,但是其中有幾點是需要說明的:
- dispatch_source_t 在本質(zhì)上是一個對象,所以我們使用強引用舔清。我們可以點擊dispatch_source_t跳轉(zhuǎn)到source.h文件看到丝里,改對象使用宏定義,進行了一系列操作定義對象鸠踪。
dispatch_source_t展開后的定義是:
@protocol OS_dispatch_source <OS_dispatch_object>
@end
typedef NSObject<OS_dispatch_source>* dispatch_source_t
也就是dispatch_source_t 就是一個NSObjective對象。對于想深入了解的同學(xué)自行百度(主要是本人實在沒有那么多精力看源碼)
- 定時器的暫停使用的是:dispatch_cancel(self.timer) 很明顯這個我們可以清楚得看到也是一個宏定義,至于他的內(nèi)部操作,請參考上一句話
- 相對于NSTimer來說GCD定時器更加精確,并且不用考慮運行模式,因為NSTimer其實是延遲把事件放到RunLoop中執(zhí)行,如果遇到其他的事件導(dǎo)致NSTimer的事件執(zhí)行錯過了運行周期,就會導(dǎo)致NSTimer的事件要到下一個周期才能運行复斥。