Tip:這篇文章筆者還未接觸Markdown語(yǔ)言所做筆記。直接復(fù)制代碼請(qǐng)點(diǎn)擊->源代碼Copy不報(bào)錯(cuò)
前言:前段時(shí)間,測(cè)試同事測(cè)試出一個(gè)問(wèn)題。那就是手機(jī)號(hào)注冊(cè)碼發(fā)送以后,發(fā)送按鈕進(jìn)入倒計(jì)時(shí),而后將程序退入后臺(tái),當(dāng)過(guò)了5分鐘以后。NSTimer就顯示的時(shí)間沒(méi)有改變。還有一種不和邏輯的現(xiàn)象就是:時(shí)間會(huì)亂序。一會(huì)5s 一會(huì)7s. (-_-)當(dāng)然了這個(gè)問(wèn)題是我沒(méi)控制好NSTimer 的NSRunloop。 為了避免這種復(fù)雜的要注意點(diǎn),我采用了GCD里邊的信號(hào)量來(lái)做倒計(jì)時(shí)按鈕。其一:在后臺(tái)也進(jìn)程也不會(huì)中斷,會(huì)按照物理時(shí)間繼續(xù)減少秒數(shù)。其二:完全避免了會(huì)亂序的情況。 廢話不多說(shuō),上代碼。
?- (void)countDownBegin:(UIButton *)sender{ NSTimeInterval seconds =60; NSDate *endTime = [NSDate dateWithTimeIntervalSinceNow:seconds];// 最后期限 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); dispatch_source_t _sometimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, queue); dispatch_source_set_timer(_sometimer, dispatch_walltime(NULL,0),1.0*NSEC_PER_SEC,0);// 每秒執(zhí)行一次 dispatch_source_set_event_handler(_sometimer, ^{ int interval = [endTime timeIntervalSinceNow]; if(interval >0) {// 更新倒計(jì)時(shí) NSString *timeStr = [NSString stringWithFormat:@"%ds", interval]; dispatch_async(dispatch_get_main_queue(), ^{ [sender setTitle:timeStr forState:UIControlStateNormal]; sender.userInteractionEnabled =NO; [sender setTitleColor:[UIColor grayColor] forState:UIControlStateNormal]; }); }else{ // 倒計(jì)時(shí)結(jié)束,關(guān)閉 dispatch_source_cancel(_sometimer); dispatch_async(dispatch_get_main_queue(), ^{ [sender setTitle:@"獲取驗(yàn)證碼"forState:UIControlStateNormal]; [sender setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; sender.userInteractionEnabled =YES; }); } }); dispatch_resume(_sometimer); }?