定時(shí)器分為兩種
第一種
//利用timer...創(chuàng)建一個定時(shí)器,這樣創(chuàng)建的定時(shí)器必須加到RunLoop里才能正常執(zhí)行
//經(jīng)測試,這里就算是一個方法內(nèi)的局部變量,定時(shí)器同樣可以正常執(zhí)行,如果定時(shí)器不能正常執(zhí)行,可以檢查是否是局部變量銷毀導(dǎo)致的,可以用一個強(qiáng)指針引用就可以
NSTimer *timer = [NSTimer timerWithTimeInterval:5.0target:selfselector:@selector(show) userInfo:nilrepeats:YES];
//用于多線程,由于系統(tǒng)現(xiàn)在只有一個線程,所以一次只能執(zhí)行一件事,那么執(zhí)行別的事件的時(shí)候,就會阻塞定時(shí)器,這時(shí)候,需要將定時(shí)器加到主線程,采用通用模式(通用模式里邊包括兩種基本RUnLoop模式,因此,在不同操作下都可以執(zhí)行定時(shí)器),
//系統(tǒng)會將1s等分成若干份,循環(huán)執(zhí)行這些事件,那么就造成同時(shí)執(zhí)行的假象
//加入RunLoop內(nèi)的定時(shí)器,會在一個間隔時(shí)間后開始執(zhí)行,例如5.0秒,就是觸發(fā),5秒之后開始執(zhí)行
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
//定時(shí)器立即執(zhí)行,通俗的講就是觸發(fā)后,定時(shí)器立即執(zhí)行一次,一個間隔時(shí)間后RunLoop內(nèi)的開始起作用(可以這樣認(rèn)為)
[timer fire];
第二種
//這種方式,創(chuàng)建后可以在一個時(shí)間間隔后直接開始運(yùn)行,而不用添加到RunLoop,并且timer是方法內(nèi)的局部變量的時(shí)候,定時(shí)器依舊可以正常執(zhí)行
//這種方式不用添加到RunLoop是因?yàn)閟cheduled的初始化方法將以默認(rèn)mode直接添加到當(dāng)前的runloop中.這就出現(xiàn)一個問題,當(dāng)有滑動操作時(shí),RunLoop的Mode就會變?yōu)?/p>
*UITrackingRunLoopMode:界面跟蹤Mode,用于ScrollView追蹤觸摸滑動,保證界面滑動時(shí)不受其他Mode的影響
這時(shí)候在默認(rèn)Mode里的定時(shí)器就暫停執(zhí)行,等Mode轉(zhuǎn)換回默認(rèn)Mode的時(shí)候繼續(xù)執(zhí)行,
為了解決這種問題,可以將scheduled這種方式創(chuàng)建的timer也添加到通用模式下Common,這樣就可以在兩種Mode下都正常執(zhí)行
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0target:selfselector:@selector(show) userInfo:nilrepeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
//這個方法還是讓定時(shí)器立刻執(zhí)行
[timer fire];
- (void)invalidate;
這個是唯一一個可以將計(jì)時(shí)器從runloop中移出的方法。
//刪除定時(shí)器
- (void)stopTimer
{
[self.timer invalidate];
self.timer =nil;
}
GCD定時(shí)器
GCD定時(shí)器非常準(zhǔn)確,不受其他操作的影響
//獲取一個全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
//GCD定時(shí)器
//1、創(chuàng)建一個GCD定時(shí)器,需要傳入一個隊(duì)列
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, queue);
//這里必須用一個強(qiáng)指針指向,如果沒有,那么timer就是一個局部變量,運(yùn)行到方法結(jié)束,timer就沒有了,等調(diào)用定時(shí)器方法的時(shí)候,timer已經(jīng)不存在了,定時(shí)器無法正常開啟
self.timer = timer;
//設(shè)置定時(shí)器的開始時(shí)間,間隔時(shí)間,和精準(zhǔn)度
//GCD的單位是納秒,內(nèi)部進(jìn)行了轉(zhuǎn)換,10的9次方
//精準(zhǔn)度:一般為0,如果對定時(shí)操作要求不精確,只要在一段時(shí)間內(nèi)執(zhí)行就可以,那么可以把精準(zhǔn)度設(shè)置的大一點(diǎn),例如10,這樣會提高程序性能
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW,2.0* NSEC_PER_SEC,0* NSEC_PER_SEC);
//設(shè)置定時(shí)器要調(diào)用的方法
dispatch_source_set_event_handler(timer, ^{
NSLog(@"GCD定時(shí)器正在運(yùn)行");
});
//啟動定時(shí)器
dispatch_resume(timer);