1. 程式人生 > >完整詳解swift GCD系列(三)dispatch_group

完整詳解swift GCD系列(三)dispatch_group

原創Blog,轉載請註明出處
http://blog.csdn.net/column/details/swift-gcd.html
一、dispatch_group
把一組任務提交到佇列中,這些佇列可以不相關,然後堅挺這組任務完成的事件。
幾個用到的函式
1、dispatch_group_create建立一個排程任務組
  1. func dispatch_group_create() -> dispatch_group_t!  

2、dispatch_group_async 把一個任務非同步提交到任務組裡
  1. func dispatch_group_async(_ group: dispatch_group_t!,  
  2.                         _ queue: dispatch_queue_t!,  
  3.                         _ block: dispatch_block_t!)  

引數:group 提交到的任務組,這個任務組的物件會一直持續到任務組執行完畢
        queue 提交到的佇列,任務組裡不同任務的佇列可以不同
        block 提交的任務


3、dispatch_group_enter/dispatch_group_leave
  1. func dispatch_group_enter(_ group: dispatch_group_t!)  
  2. func dispatch_group_leave(_ group: dispatch_group_t!)  
這兩個方法顯示的講任務組中的任務未執行完畢的任務數目加減1,這種方式用在不使用dispatch_group_async來提交任務,注意:這兩個函式要配合使用,有enter要有leave,這樣才能保證功能完整實現。也可以用這對函式來讓一個閉包關聯多個Group

4、dispatch_group_notify 用來監聽任務組事件的執行完畢
  1. func dispatch_group_notify(_ group: dispatch_group_t!,  
  2.                          _ queue: dispatch_queue_t!,  
  3.                          _ block: dispatch_block_t!)  
引數:group監聽的任務組
queue執行完畢的這個閉包所在的佇列
block執行完畢所響應的任務
5、dispatch_group_wait 設定等待時間,在等待時間結束後,如果還沒有執行完任務組,則返回。返回0代表執行成功,非0則執行失敗
  1. long dispatch_group_wait ( dispatch_group_t group, dispatch_time_t timeout );  

二、完整的程式碼解析,模擬提交三個下載任務
  1. class ViewController: UIViewController{      
  2.     override func viewDidLoad(){      
  3.         super.viewDidLoad()      
  4.         var hwcGroup = dispatch_group_create()//建立group  
  5.     var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)//全域性佇列,這個佇列為並行佇列  
  6.     var userCreateQueue =  dispatch_queue_create("com.test.helloHwc",DISPATCH_QUEUE_SERIAL)//建立一個使用者佇列,這個佇列為序列佇列  
  7.     downLoadTask1(group: hwcGroup,queue: globalQueueDefault)  
  8.     downLoadTask2(group: hwcGroup,queue: userCreateQueue)  
  9.     downLoadTask3(group: hwcGroup,queue: userCreateQueue)  
  10.     //letresult = dispatch_group_wait(hwcGroup,DISPATCH_TIME_FOREVER)  
  11.     dispatch_group_notify(hwcGroup,dispatch_get_main_queue()){  
  12.         NSLog("Group tasks are done")  
  13.     }  
  14.     println("Now viewDidLoad is done")  
  15.     }  
  16.     func downLoadTask1(#group:dispatch_group_t,queue:dispatch_queue_t){  
  17.     dispatch_group_async(group,queue){  
  18.         sleep(3)  
  19.         NSLog("Task1 is done")  
  20.     }  
  21.     }  
  22.    func downLoadTask2(#group:dispatch_group_t,queue:dispatch_queue_t){  
  23.     dispatch_group_async(group,queue){  
  24.         sleep(3)  
  25.         NSLog("Task2 is done")  
  26.     }  
  27.     }  
  28.    func downLoadTask3(#group:dispatch_group_t,queue:dispatch_queue_t){  
  29.     dispatch_group_async(group,queue){  
  30.         sleep(3)  
  31.         NSLog("Task3 is done")  
  32.     }  
  33.     }      
  34.     override func didReceiveMemoryWarning(){      
  35.         super.didReceiveMemoryWarning()      
  36.     }      
  37. }  


可以看到輸出為

  1. Now viewDidLoad is done  
  2. Task2 is done  
  3. Task1 is done  
  4. Task3 is done  
  5. Group task is done  

這裡task1提交到全域性佇列中,task2和task3提交到使用者穿件的序列佇列中,所以task1和task2同時輸出,task3在task2結束兩秒後輸出。

如果把註釋那行取消,會等待一段時間,再返回,讀者可以自己去試驗下

三、關於如何使用dispatch_group_enter/dispatch_group_leave如何使用

  1. <pre name="code" class="plain">class ViewController: UIViewController{      
  2.     override func viewDidLoad(){      
  3.         super.viewDidLoad()      
  4.         var hwcGroup = dispatch_group_create()//建立group  
  5.     var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)//全域性佇列,這個佇列為並行佇列  
  6.     for index:UInt32 in 1...3{  
  7.          dispatch_group_enter(hwcGroup)//提交了一個任務,任務數目加1  
  8.         manualDownLoad(index){  
  9.             println("Task\(index) is done")  
  10.             dispatch_group_leave(hwcGroup)//完成一個任務,任務數目減1  
  11.         }  
  12.     }  
  13.     let result = dispatch_group_wait(hwcGroup,DISPATCH_TIME_FOREVER)//等待直到完成  
  14.     dispatch_group_notify(hwcGroup,dispatch_get_main_queue()){  
  15.         println("Group tasks are done")  
  16.     }  
  17.     println("Now viewDidLoad is done")    
  18.     }  
  19.     func manualDownLoad(num:UInt32,block:()->()){  
  20.     println("Downloading task\(num)")  
  21.     sleep(num)  
  22.     block()  
  23.     }    
  24.     override func didReceiveMemoryWarning(){      
  25.         super.didReceiveMemoryWarning()      
  26.     }      
  27. }  

輸出

  1. Downloading task1  
  2. Task1 is done  
  3. Downloading task2  
  4. Task2 is done  
  5. Downloading task3  
  6. Task3 is done  
  7. Now viewDidLoad is done  
  8. Group is done  

可以看到,同步進行了下載,這裡的任務是序列的,實際消耗時間9s。當然,也可以把下載的任務提交到非同步佇列中

  1. class ViewController: UIViewController{      
  2.     override func viewDidLoad(){      
  3.         super.viewDidLoad()      
  4.         var hwcGroup = dispatch_group_create()//建立group  
  5.     var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)//全域性佇列,這個佇列為並行佇列  
  6.     for index:UInt32 in 1...3{  
  7.          dispatch_group_enter(hwcGroup)//提交了一個任務,任務數目加1  
  8.         manualDownLoad(index,queue:globalQueueDefault){  
  9.             NSLog("Task\(index) is done")  
  10.             dispatch_group_leave(hwcGroup)//完成一個任務,任務數目減1  
  11.         }  
  12.     }  
  13.     dispatch_group_notify(hwcGroup,dispatch_get_main_queue()){  
  14.         NSLog("Group tasks are done")  
  15.     }  
  16.     NSLog("Now viewDidLoad is done")      
  17.     }  
  18.     func manualDownLoad(num:UInt32,queue:dispatch_queue_t, block:()->()){  
  19.     dispatch_async(queue){  
  20.     NSLog("Downloading task\(num)")  
  21.     sleep(num)  
  22.     block()  
  23.         }  
  24.     }    
  25.     override func didReceiveMemoryWarning(){      
  26.         super.didReceiveMemoryWarning()      
  27.     }      
  28. }  

這樣的話,輸出是

  1. Downloading task1  
  2. Downloading task2  
  3. Downloading task3  
  4. Now viewDidLoad is done  
  5. Task1 is done  
  6. Task2 is done  
  7. Task3 is done  

由於三個模擬的下載任務是並行的,所以實際消耗時間3s

相關推薦

完整swift GCD系列dispatch_group

原創Blog,轉載請註明出處http://blog.csdn.net/column/details/swift-gcd.html一、dispatch_group把一組任務提交到佇列中,這些佇列可以不相關,然後堅挺這組任務完成的事件。幾個用到的函式1、dispatch_gro

完整 swift GCD系列dispatch_async;dispatch_sync;dispatch_async_f;dispatch_sync_f

為什麼要寫這個系列,因為百度了一下,找了很多都是些片面的Blog,拷貝來拷貝去的,寫的也很粗糙。 所以,我要寫這個系列,儘量把官網文件中GCD的強大功能完整的表達出來。方便自己,也方便別人,如果發現有問題,歡迎提出 本教程的計劃:在完整的看過GCD的官方文件之後,我實在想

完整GCD系列dispatch_group

/////-------------注意----------------這篇文章是在Swift 1.0時代寫的,已經不適合當前的語法。關於Swift最新版本的GCD,參見我的這篇部落格GCD精講/////-------------注意----------------一、dis

【Android 動畫】動畫之屬性動畫

大家好,在前兩篇中,我們介紹了Android的補間動畫和插值器,這一篇,我們來說下屬性動畫。 【Android 動畫】動畫詳解之補間動畫(一) 【Android 動畫】動畫詳解之插值器(二) 前言 通過前兩篇,我們已經熟悉了對View進行移動、縮放、旋轉和

C#泛型 C#泛型 C#泛型

  一、前面兩篇文章分別介紹了定義泛型型別、泛型委託、泛型介面以及宣告泛型方法:   詳解C#泛型(一)   詳解C#泛型(二)   首先回顧下如何構建泛型類: public class MyClass<T> { public void MyFunc() {

C#泛型

最大 泛型接口 oid 專用 技術分享 完全 html 回顧 連接   一、前面兩篇文章分別介紹了定義泛型類型、泛型委托、泛型接口以及聲明泛型方法:   詳解C#泛型(一)   詳解C#泛型(二)   首先回顧下如何構建泛型類: public class MyClass&

Spring Boot Actuator與深入應用:Prometheus+Grafana應用監控

《Spring Boot Actuator詳解與深入應用》預計包括三篇,第一篇重點講Spring Boot Actuator 1.x的應用與定製端點;第二篇將會對比Spring Boot Actuator 2.x 與1.x的區別,以及應用和定製2.x的端點;第三篇將會介紹Actuator metric指

完整GCD系列dispatch_after;dispatch_apply;dispatch_

本教涵蓋的內容 一、dispatch_after 二、dispatch_apply  三、dispatch_once一、dispatch_after 功能:延遲一段時間把一項任務提交到佇列中執行,返回之後就不能取消 常用來在在主佇列上延遲執行一項任務 函式原型func dispatch_after(_ wh

YUV系列----YUV420

roc 根據 系列 watermark 存儲方式 圖片 images src fff 前兩講詳細講解了YUV444以及YUV422兩種格式,實際中這兩種格式使用的相對較少,使用比較多的便是本節要梳理的YUV420格式嘍,同樣,老辦法,老套路嘍。 一、文字描述:YUV

SVM系列:線性可分支援向量機與硬間隔最大化

支援向量機概覽(support vector machines SVM) 支援向量機是一種二類分類模型。它的基本模型是定義在特徵空間上的間隔最大(間隔最大區別於感知機)線性分類器(核函式可以用非線性的分類)。 支援向量機的學習策略是間隔最大化可形式化為一個求解凸二次規劃的問題。 也等

深入淺出Mybatis原始碼系列---配置之properties與environmentsmybatis原始碼篇

上篇文章《深入淺出Mybatis原始碼系列(二)---配置簡介(mybatis原始碼篇)》我們通過對mybatis原始碼的簡單分析,可看出,在mybatis配置檔案中,在configuration根節點下面,可配置properties、typeAliases、plugins、

OSGI學習系列MANIFEST.MF

<一>在osgi專案中META-INF目錄下有一個MANIFEST.MF檔案,是載入bundle時必不可少的,如下圖所示: <二>下面簡單解釋一下其中的幾個元素 #幾個必須的

Android Camera 系列Camera API

概述 Camera 可能是接下來個人想深入學習的課題,準備新起一個系列,從個人的角度總結闡述自己對於 Android Camera 的研究過程,希望也能夠對其他想學習 Camera 的同學一些幫助。 本小節內容為 Android Camera 官方文件 的精要

Tensorflow入門系列--官方新手教程

官方教程詳解 Part 1 –資料集無法下載 在命令列模式下執行 python premade_estimator.py時會遇到報錯,錯誤原因是資料集無法下載。在iris_data.py這個檔案下,我們可以看到通過tf.keras.utils.g

Ambari系列: Ambari架構

前言 Hadoop叢集的管控一直是一個熱門的話題,對於這樣的一個應用場景,我所知道國內很早就有人研究並且取得不錯的成績,這就是EasyHadoop。它的功能主要有叢集安裝,管理,監控等功能,有興趣的朋友可以百度,這位作者的部落格有很詳細的介紹。今天,我所要重點介紹的Apac

JavaWEB--POI之EXCEL操作、優化、封裝系列--萬能POI之EXCEL匯出工具--PoiExportUtil入門篇

前面講完概述、原理以及helloworld,現在就講下怎樣的POI的EXCEL匯出工具可以適用於各種情況吧。後面再做個優化分頁的萬能POI之EXCEL匯出工具,本篇章先做個簡單的萬能POI之EXCEL匯出工具(博主已經抽象成庫,請於文末前去使用)。 文章結

深入淺出Mybatis系列---配置之properties與environmentsmybatis原始碼篇

上篇文章《深入淺出Mybatis系列(二)---配置簡介(mybatis原始碼篇)》我們通過對mybatis原始碼的簡單分析,可看

Kafka 系列—— Kafka 生產者

一、生產者傳送訊息的過程 首先介紹一下 Kafka 生產者傳送訊息的過程: Kafka 會將傳送訊息包裝為 ProducerRecord 物件, ProducerRecord 物件包含了目標主題和要傳送的內容,同時還可以指定鍵和分割槽。在傳送 ProducerRecord 物件前,生產者會先把鍵和值物件序列

:python 對象類型一:數字

結果 dom 運行 精度 升級 方法 函數 般的 代碼 一:python 的數字類型: a)整數和浮點數 b)復數 c)固定精度的十進制數 d)有理分數 e)集合 f)布爾類型 g)無窮的整數精度 h)各種數字內置函數和模塊 二:各種數字類型的詳解   1,數字常量:pyt

緩沖區溢出實戰教程系列:利用OllyDbg了程序運行機制

成了 代碼段 下界 urn 方便 htm oca 相差 14. 想要進行緩沖區溢出的分析與利用,當然就要懂得程序運行的機制。今天我們就用動態分析神器ollydbg來了解一下在windows下程序是如何運行的。 戳這裏看之前發布的文章: 緩沖區溢出實戰教程系列(一):