GCD的使用

  • Grand Central Dispatch:純C語言
  • GCD為多核的并行而生
  • GCD自動管理線程生命周期(創建,調度,銷毀)

1.GCD的線程分配規則

2.四個重要概念

  • 同步異步說的是函數的開啟新線程的能力
    • 同步:不具備開啟新線程能力,只在當前線程中執行任務
    • 異步:具備開啟新線程的能力,可在多條線程中執行任務
  • 并發串行說的是任務的執行順序
    • 串行:任務一個接一個的執行
    • 并發:任務一起執行

3.使用語法:

  • 并發隊列
dispatch_queue_t queue = dispatch_queue_create("downloadA", DISPATCH_QUEUE_CONCURRENT);
  • 串行隊列
dispatch_queue_t queueA = dispatch_queue_create("downloadB", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queueB = dispatch_queue_create("downloadB", NULL); 
  • 全局并發隊列
// 獲取全局并發隊列
dispatch_queue_t queueA = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queueB = dispatch_get_global_queue(0, 0);
  • 主隊列
//1.獲得主隊列
dispatch_queue_t queue = dispatch_get_main_queue();
  • 異步函數
dispatch_async(queue, ^{
        NSLog(@"download1----%@",[NSThread currentThread]);
    });
  • 同步函數
dispatch_sync(queue, ^{
        NSLog(@"download1----%@",[NSThread currentThread]);
    });
4.線程間通信
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 執行耗時的異步操作...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主線程,執行UI刷新操作
        });
});
5.GCD常用函數

5.1.延遲執行

    1. 延遲執行的第一種方法:performSelector
[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
  • 2.延遲執行的第二種方法:NSTimer
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
  • 3.延遲執行的第三種方法:GCD
 dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
/*
     第一個參數:DISPATCH_TIME_NOW 從現在開始計算時間
     第二個參數:延遲的時間 2.0 GCD時間單位:納秒
     第三個參數:隊列
     */
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"GCD----%@",[NSThread currentThread]);
    });

5.2.一次性代碼

//不能放在懶加載中的,應用場景:單例模式
-(void)once
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"---once----");
    });
}

5.3.柵欄函數:

  • 柵欄函數不能使用全局并發隊列,否則 dispatch_barrier_async 的作用會和 dispatch_async 的作用一樣
    // 創建并發隊列
    dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
    // 并發隊列 + 異步函數任務1
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<100; i++) {
            NSLog(@"download1-%zd-%@",i,[NSThread currentThread]);
        }
    });
    // 并發隊列 + 異步函數任務2
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<100; i++) {
            NSLog(@"download2-%zd-%@",i,[NSThread currentThread]);
        }
    });
    //并發隊列 + 柵欄函數
    dispatch_barrier_async(queue, ^{
        NSLog(@"+++++++++++++++++++++++++++++");
    });
    // 并發隊列 + 異步函數任務3
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<100; i++) {
            NSLog(@"download3-%zd-%@",i,[NSThread currentThread]);
        }
    });

5.4.快速迭代

    /*
     迭代函數
     第一個參數:遍歷的次數
     第二個參數:隊列(并發隊列)
     第三個參數:index 索引
     */
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
    // 執行10次代碼,index順序不確定
});

6.隊列組

-(void)group1
{
    //1.創建隊列
    dispatch_queue_t queue =dispatch_get_global_queue(0, 0);
    //2.創建隊列組
    dispatch_group_t group = dispatch_group_create();
    
    //3.異步函數
    /*
     1)把任務添加到隊列中
     2)隊列添加到隊列組
     3)監聽任務的執行情況, 通知group
     */
    dispatch_group_async(group, queue, ^{
        NSLog(@"1----%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"2----%@",[NSThread currentThread]);
    });
    
    // 當隊列組中所有的任務都執行完畢, 進入到下面的方法
    dispatch_group_notify(group, queue, ^{
        NSLog(@"-------dispatch_group_notify-------");
    });
}
  • 使用異步函數,在并發隊列中可開啟多條線程;在串行隊列中只開啟一條線程;在主隊列中不能開啟新線程。
  • 注意:同步函數 + 主隊列 = 死鎖
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。