iOS開發(fā)——多線程完成短信獲取按鈕倒計時

現(xiàn)在的APP應用中,用手機獲取短信驗證碼是非常常見的一個功能,而往往要求的效果就是在按下獲取驗證碼之后,驗證碼的按鈕開始倒計時,例如30秒后重新獲取。而我們?nèi)绾蝸硗瓿蛇@個效果呢,其實很簡單,用一個定時器來計時,設(shè)置定時器的時間為UIButton的Title,而這個步驟我們一般用多線程的定時器dispatch source來定時產(chǎn)生事件。

在網(wǎng)上看了別人寫的代碼,復用性比較差,沒有對這個方法進行良好的封裝,我在這里貼一段修改后的代碼,基本上大家黏貼過去就能復用。而后面我會解釋這個代碼的多線程方面的一些問題。

#pragma mark - 倒計時獲取驗證碼
-(void)changeTimeOut:(int)timeOut btnTag:(int)btnTag{
    __block int timeout=timeOut;
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t _timer=dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0*NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(_timer, ^{
        if (timeout<=0) {
            dispatch_source_cancel(_timer);
            //dispatch_release(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //倒計時結(jié)束
                _smsCodeBtn=(UIButton*)[self.view viewWithTag:[[NSString stringWithFormat:@"%d",btnTag] intValue]];
                [_smsCodeBtn setTitle:@"重新獲取驗證碼" forState:UIControlStateNormal];
                [_smsCodeBtn setUserInteractionEnabled:YES];
                [_smsCodeBtn setTitleColor:[UIColor colorWithRed:53.0f/255.0f   green:53.0f/255.0f blue:68.0f/255.0f alpha:1] forState:UIControlStateNormal];
                [_smsCodeBtn.layer setBorderColor:[UIColor colorWithRed:53.0f/255.0f green:53.0f/255.0f blue:68.0f/255.0f alpha:1].CGColor];
            });
        }else{
            NSString* strTime=[NSString stringWithFormat:@"%d秒后重新獲取",(int)(timeout)];
            dispatch_async(dispatch_get_main_queue(), ^{
                //倒計時
                _smsCodeBtn=(UIButton*)[self.view viewWithTag:[[NSString stringWithFormat:@"%d",(int)btnTag] intValue]];
                [_smsCodeBtn setTitle:strTime forState:UIControlStateNormal];
                [_smsCodeBtn setTitleColor:[UIColor colorWithRed:153.0f/255.0f green:153.0f/255.0f blue:153.0f/255.0f alpha:1] forState:UIControlStateNormal];
                [_smsCodeBtn.layer setBorderColor:[UIColor colorWithRed:153.0f/255.0f green:153.0f/255.0f blue:153.0f/255.0f alpha:1].CGColor];
                [_smsCodeBtn setUserInteractionEnabled:NO];
            });
            timeout--;
        }
    });
    dispatch_resume(_timer);
}

這段代碼中smsCodeBtn就是我定義的獲取短信驗證碼的UIButton,你們復制下去只要把frame屬性和ui屬性改一改,就完全可以直接用了。

那么接下來我們來講講這段代碼中多線程的問題。

首先我們先用dispatch_get_global_queue來開啟一個全局隊列,之后用dispatch_source_t來產(chǎn)生定時事件。所有定時器dispatch_source都是間隔定時器,一旦創(chuàng)建,會按你指定的間隔定期遞送事件。你需要為定時器dispatch_source指定一個期望的定時器事件精度,也就是leeway值,讓系統(tǒng)能夠靈活地管理電源并喚醒內(nèi)核。例如系統(tǒng)可以使用leeway值來提前或延遲觸發(fā)定時器,使其更好地與其他系統(tǒng)事件結(jié)合。創(chuàng)建自己的定時器時,你應該盡量指定一個leeway值。

就算你指定的leeway值為0,也不要期望定時器能夠按照精確地納秒來觸發(fā)事件,系統(tǒng)會盡可能地滿足你的需求,但是無法保證完全精確的觸發(fā)時間。

如果你使用dispatch_walltime函數(shù)來設(shè)置定時器dispatch_source,則定時器會根據(jù)掛鐘時間來跟蹤,這種定時器比較適合觸發(fā)間隔相對比較大的場合,可以防止定時器觸發(fā)時間出現(xiàn)太大誤差。

dispatch_time類型的時間我們可以通過dispatch_time來創(chuàng)建,也可以通過dispatch_walltime來創(chuàng)建。前者創(chuàng)建的時間多以第一個參數(shù)為參照物,之后過多久執(zhí)行任務。后者多用于創(chuàng)建絕對時間,如某年某月某日某時某分執(zhí)行某任務,比如鬧鐘的設(shè)置。

最后我們用dispatch_source_set_event_handler這個方法來創(chuàng)建我們要完成的任務,很簡單的語句,一個block閉包,里面的內(nèi)容當然是自由發(fā)揮的咯。

所以交代清楚GCD中時間事件,這段代碼就非常容易理解了。

代碼很短也就不傳到Github上的demo了。如果有寫的不對的地方,歡迎交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Dispatch Sources 現(xiàn)代系統(tǒng)通常提供異步接口,允許應用向系統(tǒng)提交請求,然后在系統(tǒng)處理請求時應用可以繼...
    YangPu閱讀 388評論 0 0
  • Dispatch Sources 現(xiàn)代系統(tǒng)通常提供異步接口,允許應用向系統(tǒng)提交請求,然后在系統(tǒng)處理請求時應用可以繼...
    好雨知時節(jié)浩宇閱讀 3,918評論 2 5
  • 支持原創(chuàng) 現(xiàn)代系統(tǒng)通常提供異步接口,允許應用向系統(tǒng)提交請求,然后在系統(tǒng)處理請求時應用可以繼續(xù)處理自己的事情。Gra...
    John_LS閱讀 3,690評論 3 2
  • iOS 多線程系列 -- 基礎(chǔ)概述iOS 多線程系列 -- pthreadiOS 多線程系列 -- NSThrea...
    shannoon閱讀 1,670評論 0 5
  • 程序中同步和異步是什么意思?有什么區(qū)別? 解釋一:異步調(diào)用是通過使用單獨的線程執(zhí)行的。原始線程啟動異步調(diào)用,異步調(diào)...
    風繼續(xù)吹0閱讀 1,121評論 1 2

友情鏈接更多精彩內(nèi)容