早期咱們使用延時執行的方法都是用NSObject 類提供的,performSelector:系列的方法,具體有哪些咱們看一下數組
咱們通常讓某個對象延時執行某個方法都會調用包含 afterDelay這個參數的方法,此參數即表明延時多長時間執行 ,可是這一系列的方法的參數都只接受繼承自NSObject類得對象,也就是說若是咱們要向其中傳入基本的數據類型,那就必須涉及到數據類型轉換,這顯然會增長開銷,並且這一系列的方法最多也就能傳如一個參數,若是咱們要傳多個參數怎麼辦呢 ,若是想繼續使用這個方法,那咱們就必須把多個參數寫入數組或字典中去,而後把數組或字典對象傳給這個方法,那麼着就又會增長咱們插入數組或字典,解析數組或字典的代碼 ,數據量達到必定狀況的話,這個開銷是可想而知的,並且咱們還要知道數組和字典中得每一個對象都表明什麼,很麻煩;async
不過咱們能夠用塊來解決這一問題 ,GCD 爲咱們提供了一個演示執行的塊函數,其具體定義以下:ide
void dispatch_after ( dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block );函數
咱們在調用此方法的時候,系統也考慮的很周到,當咱們寫入dispatch_after時,這個完整的函數就會呈現出來,咱們看一下spa
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ });
調用很方便,若是咱們想把裏面的內容放到主線程中去運行的話,也很方便,例如:線程
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{ [son study]; }); });
還記得當時有一個問題,就是想給UIButton的點擊事件加點料,讓系統中的全部的按鈕都禁止快速點擊或者連擊,當時問了看了好多博客,都沒有好的解決方案,前篇一概的討論或者建議,都是使用performSelector:afterDelay這種方法,可是這樣的話,我還要實現另外一個方法 。後來是這麼解決的呢 ,這裏再次引用我以前寫的內容,重寫父類函數,而後使用GCD的dispatch_after 方法解決;code
具體實現以下:orm
// // CommonButton.h // CommonButton // // Created by pk on 14/12/24. // Copyright (c) 2014年 pk. All rights reserved. // #import <UIKit/UIKit.h> @interface CommonButton : UIButton @end
// // CommonButton.m // CommonButton // // Created by pk on 14/12/24. // Copyright (c) 2014年 pk. All rights reserved. // #import "CommonButton.h" @implementation CommonButton /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ - (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { [super sendAction:action to:target forEvent:event]; self.enabled = NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.enabled = YES; }); } @end
這樣的實現,很清楚,結構簡明,使用簡單,想使用此方法,只要將改一下類得繼承就行;對象
總結:performSelector 系列方法所能處理的選擇器太過於侷限性了 ,選擇器的返回值類型和參數的個數都會受到限制;blog
而dispatch_after就沒有這些問題,另外,若是想把任務放在另外一個線程上執行,最好不要用performSelector系列方法,而應該把任務封裝到塊裏,而後調用GCD的相關方法來實現就行