iOS 高效開發-----延時執行用GCD


早期我們使用延時執行的方法都是用NSObject 類提供的,performSelector:系列的方法,具體有哪些我們看一下

我們一般讓某個對象延時執行某個方法都會調用包含  afterDelay這個參數的方法,此參數即代表延時多長時間執行 ,但是這一系列的方法的參數都只接受繼承自NSObject類得對象,也就是說如果我們要向其中傳入基本的數據類型,那就必須涉及到數據類型轉換,這顯然會增加開銷,而且這一系列的方法最多也就能傳如一個參數,如果我們要傳多個參數怎么辦呢 ,如果想繼續使用這個方法,那我們就必須把多個參數寫入數組或字典中去,然后把數組或字典對象傳給這個方法,那么着就又會增加我們插入數組或字典,解析數組或字典的代碼 ,數據量達到一定情況的話,這個開銷是可想而知的,而且我們還要知道數組和字典中得每個對象都代表什么,很麻煩;

不過我們可以用塊來解決這一問題 ,GCD 為我們提供了一個演示執行的塊函數,其具體定義如下:

void dispatch_after ( dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block );

我們在調用此方法的時候,系統也考慮的很周到,當我們寫入dispatch_after時,這個完整的函數就會呈現出來,我們看一下

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 方法解決;

具體實現如下:

//
//  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 系列方法所能處理的選擇器太過於局限性了 ,選擇器的返回值類型和參數的個數都會受到限制;

    而dispatch_after就沒有這些問題,另外,如果想把任務放在另一個線程上執行,最好不要用performSelector系列方法,而應該把任務封裝到塊里,然后調用GCD的相關方法來實現就行

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM