GCD的基礎用法

什么是GCD?

全稱Grand Center Dispatch,是純C語言的,提供了非常強大的函數,是蘋果公司為了解決多核的并行運算而推出的。
優點:
1.自動利用更多的CPU內核
2.自動管理線程的生命周期
3.使用簡單(確定想要做的事情(任務),然后添加到隊列,按照指定的同步、異步方式執行,CGD會自動將隊列中的任務取出放到對應的線程中執行,任務的取出遵循FIFO原則,先進先出)

核心概念:
1.任務:需要執行的事情
2.隊列:存放任務的集合

基礎用法

隊列、函數知識點

串行隊列:一個接一個的調度任務
并發隊列:可以同時調度多個任務
主隊列:全局串行隊列,由主線程串行調度任務,并且只有一個
全局隊列:沒有名稱的并發隊列

同步執行(sync):當前指令不完成,就不會執行下一條指令,不會開啟新線程
異步執行(async):當前指令不完成,同樣可以執行下一條指令,會開啟新線程

注意點:
主隊列+ 同步執行 會產生死鎖

創建隊列
/// 創建串行隊列
// OC
- (void)creatSerialQueue {
    /**
     label: 隊列標識
     dispatch_queue_attr_t: 隊列屬性,DISPATCH_QUEUE_SERIAL串行,DISPATCH_QUEUE_CONCURRENT并行
     */
    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue, ^{
        NSLog(@"任務1");
        // 睡3秒
        [NSThread sleepForTimeInterval:3.0];
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"任務2");
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"任務3");
    });
}

// Swift
func creatSerialtQueue() -> () {
        // 默認初始化方法創建的就是一個串行隊列
        let serialQueue = DispatchQueue(label: "serialQueue")
        serialQueue.async {
            print("任務1")
            // 睡3秒
            sleep(3)
        }
        serialQueue.async {
            print("任務2")
        }
        serialQueue.async {
            print("任務3")
        }
    }

雖然有sleep 3秒但是依然會等待、按順序執行
2017-04-03 11:04:21.441 OC-GCD測試[1943:158578] 任務1
2017-04-03 11:04:24.446 OC-GCD測試[1943:158578] 任務2
2017-04-03 11:04:24.446 OC-GCD測試[1943:158578] 任務3

/// 創建并行隊列
// OC
- (void)creatConcurrentQueue {
    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concurrentQueue, ^{
        NSLog(@"任務1");
        // 睡3秒
        [NSThread sleepForTimeInterval:3.0];
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"任務2");
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"任務3");
    });
}

// Swift
func creatConcurrentQueue() -> () {
        // 創建并發的隊列,在attributes中聲明concurrent
        let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: DispatchQueue.Attributes.concurrent)
        concurrentQueue.async {
            print("任務1")
            // 睡3秒
            sleep(3)
        }
        concurrentQueue.async {
            print("任務2")
        }
        concurrentQueue.async {
            print("任務3")
        }
    }

sleep 3秒不會等待、并發執行
2017-04-03 11:01:26.550 OC-GCD測試[1897:154504] 任務2
2017-04-03 11:01:26.550 OC-GCD測試[1897:154507] 任務1
2017-04-03 11:01:26.550 OC-GCD測試[1897:154505] 任務3

同步執行(不會開啟線程)
// OC
- (void)synTest {
    // 獲取一個全局隊列
    dispatch_queue_t queque = dispatch_get_global_queue(0, 0);
    
    // 創建一個任務
    void(^task)() = ^() {
        NSLog(@"當前線程:%@", [NSThread currentThread]);
    };
    
    // 執行任務
    dispatch_sync(queque, task);
}

// Swift
func synTest() -> () {
        // 獲取一個全局隊列
        let queue = DispatchQueue.global()
        
        // 創建一個任務
        let task = {
            print("當前線程:\(Thread.current)")
        }
        
        // 執行任務
        queue.sync(execute: task)
    }

控制臺輸出結果(同步不具備開啟線程的能力,在當前線程(主線程)執行,所以輸出number = 1, name = main

<NSThread: 0x6000000770c0>{number = 1, name = main}

異步執行(會開啟新的線程)
// OC
- (void)asynTest {
    // 獲取一個全局隊列
    dispatch_queue_t queque = dispatch_get_global_queue(0, 0);
    
    // 創建一個任務
    void(^task)() = ^() {
        NSLog(@"當前線程:%@", [NSThread currentThread]);
    };
    
    // 執行任務
    dispatch_async(queque, task);
}

// Swift
func asynTest() -> () {
        // 獲取一個全局隊列
        let queue = DispatchQueue.global()
        
        // 創建一個任務
        let task = {
            print("當前線程:\(Thread.current)")
        }
        
        // 執行任務
        queue.async(execute: task)
    }

控制臺輸出結果(異步會開啟新的線程的,所以輸出number = 3, name = (null)

<NSThread: 0x608000267440>{number = 3, name = (null)}

異步拉回主線程
// OC
- (void)mainQueueTest {
   // 獲取全局隊列
   dispatch_queue_t globalQueueue = dispatch_get_global_queue(0, 0);
   dispatch_async(globalQueueue, ^{
       NSLog(@"異步執行操作");
       [NSThread sleepForTimeInterval:3];
       
       // 獲取主隊列
       dispatch_queue_t mainQueueue = dispatch_get_main_queue();
       dispatch_async(mainQueueue, ^{
           NSLog(@"拉回主線程更新UI");
       });
   });
}

// Swift
func mainQueueTest() -> () {
       DispatchQueue.global().async {
           print("異步執行操作")
           sleep(3)
           DispatchQueue.main.async {
               print("拉回主線程更新UI")
           }
       }
   }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • - (void)viewDidLoad { [super viewDidLoad]; // [self asyn...
    楊帥iOS閱讀 341評論 0 0
  • 從哪說起呢? 單純講多線程編程真的不知道從哪下嘴。。 不如我直接引用一個最簡單的問題,以這個作為切入點好了 在ma...
    Mr_Baymax閱讀 2,833評論 1 17
  • 說明:本文主要用于個人能力的提高,主要參考于簡書,Swift版本為3.0 1. 簡介 什么是GCD呢?我們先看看百...
    CocoaC_Wang閱讀 1,419評論 0 4
  • 今晚去星海音樂廳廳聽了一個講座,關于當代小提琴家的介紹。由于之前就在音樂廳附近收過一張違章停車的罰單,而自己有點小...
    貓小開閱讀 697評論 2 49
  • 每個人都會把自己扮演各種的角色,生活中的,工作的,家人眼中的,朋友眼中的,我們都想把每一個角色做好,卻都好像又沒有...
    小2貨閱讀 534評論 0 1