GCD多線程的使用


1. 什麼是GCD
全稱Grand Central Dispatch,可譯爲中樞調度器”,C語言,提供了非常多強大的函數
優點:
GCD自動管理線程的生命週期(創建線程,調度任務,銷燬線程), 自動利用更多的CPU內核(比如雙核,四核)
GCD的任務的取出遵循隊列的FIFO原則:先進先出,後進後出
 容易混淆的術語
 1>.同步和異步主要影響:能不能開啓新的線程
 同步:在當前線程中執行任務,不具備開啓新線程的能力
 異步:在新的線程中執行任務,具備開啓新線程的能力
 2>.併發和串行主要影響:任務的執行方式
 
併發:多個任務併發(同時)執行
 串行:一個任務執行完畢後,再執行下一個任務
 GCD中有2個用來執行任務的函數
2.執行的任務:
 1>.用同步的方式執行任務
 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
 queue:
隊列
 block:
任務

 2>.
用異步的方式執行任務
 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
隊列的類型
 GCD
的隊列可以分爲2大類型
 
併發隊列(Concurrent Dispatch Queue
 
可以讓多個任務併發(同時)執行(自動開啓多個線程同時執行任務)
 併發功能只有在異步(dispatch_async)函數下才有效
 串行隊列(Serial Dispatch Queue
 
讓任務一個接着一個地執行(一個任務執行完畢後,再執行下一個任務)
 
併發隊列 /****   重要   *****/
 GCD默認已經提供了全局的併發隊列,供整個應用使用,不需要手動創建
 
使用

 dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
 
返回值 dispatch_queue_t 隊列
 
參數 long identifier 全局併發隊列優先級
 參數 unsigned long flags=0 此參數暫時無用,用0即可
 //全局併發隊列的優先級
 #define DISPATCH_QUEUE_PRIORITY_HIGH 2

 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
默認(中)
 #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 後臺


線程間的使用:
//異步併發執行:

3.  GCD 延遲執行
例如:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
   
NSLog(@"----touchesBegan");
#if 0
    //錯誤的做法 缺點:卡住當前線程
    [NSThread sleepForTimeInterval:
3
];
    NSLog(
@"---下載圖片");
    NSLog(
@"----downloadfinished");
#endif
   
#if 0
2> 1.調用NSObject的方法
    //一旦定製好 延遲任務後 不會卡住當前線程, 3秒後回到主線程中執行download方法不會卡住當前線程
    [self performSelector:@selector(download) withObject:nil afterDelay:3.0f];
    NSLog(
@"----downloadfinished");
#endif
   
#if 0
    //3秒後回到主線程中執行block中的代碼,不會造成卡頓
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(
3 * NSEC_PER_SEC)), queue, ^{
        NSLog(
@"----下載圖片 %@"
,[NSThread currentThread]);
    });
    NSLog(
@"----downloadfinished");
#endif

    //3秒後在新建的子線程中執行block中的代碼,不會造成卡頓
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
       
NSLog(@"----下載圖片 %@",[NSThread currentThread]);
    });
   
NSLog(@"----downloadfinished"
);
}
- (void)download
{
   
NSLog(@"---下載圖片 %@",[NSThread currentThread]);
}


4.一次性代碼
- (void)download
{
   
//一次性代碼 使用dispatch_once_t函數能保證某段代碼在程序運行過程中只被執行1次(block中的代碼默認是線程安全的)
   
//永遠只執行一次,從函數的開始到結束
   
static dispatch_once_t onceToken;
   
dispatch_once(&onceToken, ^{
       
NSLog(@"下載圖片"
);
    });
//    if (self.hasExcuted) return;
//    NSLog(@"下載圖片");
//    self.hasExcuted = YES;
}

五:  GCD 隊列組:

1.隊列組可以解決如下需求
首先:分別異步執行2個耗時操作
其次:等2個異步操作都執行完畢後,再回到主線程執行操作
//1.隊列組
   
dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, ^{
       
//下載圖片等操作
       
    });
   
//(保證組裏面所有的任務都執行完成後 再執行notify函數裏面的block
    dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, ^{
       
//執行圖片合併等操作
        ……..
       
//回到主線程顯示

        dispatch_async(dispatch_get_main_queue(), ^{
           
//顯示內容等操作
        });
    });
    
要求:
//例如:
//1分別下載兩張圖片:大圖片 logo
//2合併兩張圖片
//3顯示到一個imageView

//百度logo http://img.baidu.com/img/baike/logo-baike.png


此處還可以用異步併發隊列來實現此功能
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章