定時(shí)器分為兩種
第一種
//利用timer...創(chuàng)建一個(gè)定時(shí)器,這樣創(chuàng)建的定時(shí)器必須加到RunLoop里才能正常執(zhí)行
//經(jīng)測試,這里就算是一個(gè)方法內(nèi)的局部變量绎谦,定時(shí)器同樣可以正常執(zhí)行,如果定時(shí)器不能正常執(zhí)行栈戳,可以檢查是否是局部變量銷毀導(dǎo)致的银觅,可以用一個(gè)強(qiáng)指針引用就可以
NSTimer *timer = [NSTimer timerWithTimeInterval:5.0target:selfselector:@selector(show) userInfo:nilrepeats:YES];
//用于多線程攒砖,由于系統(tǒng)現(xiàn)在只有一個(gè)線程夯膀,所以一次只能執(zhí)行一件事继蜡,那么執(zhí)行別的事件的時(shí)候回俐,就會(huì)阻塞定時(shí)器逛腿,這時(shí)候,需要將定時(shí)器加到主線程仅颇,采用通用模式(通用模式里邊包括兩種基本RUnLoop模式单默,因此,在不同操作下都可以執(zhí)行定時(shí)器)忘瓦,
//系統(tǒng)會(huì)將1s等分成若干份搁廓,循環(huán)執(zhí)行這些事件,那么就造成同時(shí)執(zhí)行的假象
//加入RunLoop內(nèi)的定時(shí)器耕皮,會(huì)在一個(gè)間隔時(shí)間后開始執(zhí)行枚抵,例如5.0秒,就是觸發(fā)明场,5秒之后開始執(zhí)行
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
//定時(shí)器立即執(zhí)行汽摹,通俗的講就是觸發(fā)后,定時(shí)器立即執(zhí)行一次苦锨,一個(gè)間隔時(shí)間后RunLoop內(nèi)的開始起作用(可以這樣認(rèn)為)
[timer fire];
第二種
//這種方式逼泣,創(chuàng)建后可以在一個(gè)時(shí)間間隔后直接開始運(yùn)行,而不用添加到RunLoop舟舒,并且timer是方法內(nèi)的局部變量的時(shí)候拉庶,定時(shí)器依舊可以正常執(zhí)行
//這種方式不用添加到RunLoop是因?yàn)閟cheduled的初始化方法將以默認(rèn)mode直接添加到當(dāng)前的runloop中.這就出現(xiàn)一個(gè)問題,當(dāng)有滑動(dòng)操作時(shí)秃励,RunLoop的Mode就會(huì)變?yōu)?/p>
*UITrackingRunLoopMode:界面跟蹤Mode氏仗,用于ScrollView追蹤觸摸滑動(dòng),保證界面滑動(dòng)時(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];
//這個(gè)方法還是讓定時(shí)器立刻執(zhí)行
[timer fire];
- (void)invalidate;
這個(gè)是唯一一個(gè)可以將計(jì)時(shí)器從runloop中移出的方法慷蠕。
//刪除定時(shí)器
- (void)stopTimer
{
[self.timer invalidate];
self.timer =nil;
}
GCD定時(shí)器
GCD定時(shí)器非常準(zhǔn)確,不受其他操作的影響
//獲取一個(gè)全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
//GCD定時(shí)器
//1食呻、創(chuàng)建一個(gè)GCD定時(shí)器流炕,需要傳入一個(gè)隊(duì)列
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, queue);
//這里必須用一個(gè)強(qiáng)指針指向,如果沒有仅胞,那么timer就是一個(gè)局部變量每辟,運(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捐名,如果對(duì)定時(shí)操作要求不精確,只要在一段時(shí)間內(nèi)執(zhí)行就可以闹击,那么可以把精準(zhǔn)度設(shè)置的大一點(diǎn)镶蹋,例如10,這樣會(huì)提高程序性能
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)行");
});
//啟動(dòng)定時(shí)器
dispatch_resume(timer);