3棋傍、GCD-swift

GCD 一直以來是基于 c 語言的救拉。
apple 為了使 GCD 使用更加的 swift 化。 對 GCD 進行了進行了改造瘫拣。
以下所有代碼都是基于 Swift3.0


先來段廢話:
(不了解基本概念的建議看看近上, 了解的直接略過!)

GCD

Grand Central Dispatch (GCD)是Apple開發(fā)的一個多核編程的較新的解決方法。它主要用于優(yōu)化應(yīng)用程序以支持多核處理器以及其他對稱多處理系統(tǒng)壹无。它是一個在線程池模式的基礎(chǔ)上執(zhí)行的并行任務(wù)。在Mac OS X 10.6雪豹中首次推出感帅,也可在IOS 4及以上版本使用斗锭。

GCD 中兩個重要重要概念 —— 隊列 & 任務(wù)

隊列

隊列是一種特殊的線性表,采用FIFO(先進先出)的原則失球,即新任務(wù)總是被插入到隊列的末尾岖是,而讀取任務(wù)的時候總是從隊列的頭部開始讀取。每讀取一個任務(wù)实苞,則從隊列中釋放一個任務(wù)豺撑。

隊列的主要作用是用來存放任務(wù)。

GCD會自動將隊列中的任務(wù)取出黔牵,放到對應(yīng)的線程中執(zhí)行聪轿。

**隊列分類: **

  • 串行隊列(Serial Dispatch Queue): 讓任務(wù)一個接著一個地執(zhí)行(一個任務(wù)執(zhí)行完畢后,再執(zhí)行下一個任務(wù)

  • 并發(fā)隊列(Concurrent Dispatch Queue): 可以讓多個任務(wù)并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行任務(wù)), 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
    > 由于隊列同步執(zhí)行不具有開啟線程的能力猾浦,異步執(zhí)行才可以開啟線程陆错。
    > 并發(fā)隊列在異步執(zhí)行才有效。

隊列執(zhí)行任務(wù)的方式:

  • 同步:在當(dāng)前線程中執(zhí)行金赦,當(dāng)前代碼不執(zhí)行完音瓷,就不能夠執(zhí)行下一條代碼。會阻塞當(dāng)前線程夹抗。

  • 異步:在另一條線程中執(zhí)行(不用等待當(dāng)前代碼執(zhí)行完绳慎,就能夠執(zhí)行下一條),不會阻塞當(dāng)前線程漠烧。

常見隊列:

為了方便 GCD 使用杏愤,蘋果默認(rèn)提供了主隊列和全局隊列。 我們不需要創(chuàng)建只需要獲取沽甥。

  • 主隊列 (串行)
let mainQueue = DispatchQueue.main
  • 全局隊列 (并發(fā))
let globalQueue = DispatchQueue.global()

全局隊列默認(rèn)是并發(fā)隊列声邦,在不進行第三方框架或者大型的商業(yè)應(yīng)用開發(fā),全局隊列基本夠用摆舟。

任務(wù)

需要執(zhí)行操作, 任務(wù)是使用閉包( oc: block) 封裝的代碼塊亥曹。

廢話到此完畢!


1. 項目開發(fā)中 GCD 代碼使用

print("DispatchQueue.main.sync: befor", Thread.current)
DispatchQueue.global().async {
       print("DispatchQueue.global().async: Time task", Thread.current, "\n --: 耗時操作在后臺線程中執(zhí)行恨诱!")
            
      DispatchQueue.main.async {
          print("DispatchQueue.main.async: update UI", Thread.current, "\n --: 耗時操作執(zhí)行完畢后在主線程更新 UI 界面媳瞪!")
      }
}
print("DispatchQueue.main.sync: after", Thread.current)


// 打印:
DispatchQueue.main.sync: befor <NSThread: 0x60800007abc0>{number = 1, name = main}
DispatchQueue.main.sync: after <NSThread: 0x60800007abc0>{number = 1, name = main}
DispatchQueue.global().async: Time task <NSThread: 0x6080002662c0>{number = 3, name = (null)} 
 --: 耗時操作在后臺線程中執(zhí)行照宝!
DispatchQueue.main.async: update UI <NSThread: 0x60800007abc0>{number = 1, name = main} 
 --: 耗時操作執(zhí)行完畢后在主線程更新 UI 界面蛇受!

/*
 after 執(zhí)行的先后順序是不確定的。是由 GCD 決定厕鹃。
這里牽扯到一個概念: 線程間通訊兢仰! 說白的就是在線程間進行數(shù)據(jù)(信號)的傳遞乍丈。
*/

如果你只是單純的找 GCD 在 swift 中怎么使用,看到這里你基本可以關(guān)掉這篇博客把将,開心的寫代碼去了轻专。


2. GCD 使用 —— 精講

先來了解 GCD 在 Swift 中的變化
GCD 框架頭文件改變

import Dispatch.base         // 沒有實質(zhì)性內(nèi)容
import Dispatch.block        // 沒有實質(zhì)性內(nèi)容
import Dispatch.data         // 沒有實質(zhì)性內(nèi)容
import Dispatch.group
import Dispatch.io
import Dispatch.object
import Dispatch.once        // 沒有實質(zhì)性內(nèi)容
import Dispatch.queue
import Dispatch.semaphore
import Dispatch.source
import Dispatch.time
import Dispatch
import os_object

// 在 swift3.0 中新加的, OS_object 繼承自 NSObject
// 在 GCD 中所有的對象都間接的繼承自 NSObject察蹲。
import os_object
open class OS_object : NSObject {
}

Swift 中最大的變化其實就是更加的面相對象了,使用更加的方便簡潔洽议,擺脫了 OC 時代函數(shù)式的使用方式宗收。

GCD 使用先來個個人小的總結(jié):

口訣:同步不開異步開,串行開1條亚兄,并行開多條混稽。

來,跟著哥一起念儿捧。( 我怕你們打我荚坞,你們還是別念了,我解釋一下菲盾。)

同步不開異步開颓影,串行開1條,并行開多條懒鉴。
單純這么簡單的看是有誤解的诡挂, 在我的評論中就可以看到。

具體的意思是:
隊列中的任務(wù)同步執(zhí)行临谱,隊列就不具有開啟線程的能力璃俗, 隊列中的任務(wù)異步執(zhí)行,隊列就具有開啟線程的能力悉默。
(同步和異步執(zhí)行決定的是否有開啟線程的能力)

如果隊列具 **有開啟線程的能力 (隊列任務(wù)異步執(zhí)行) ** 且隊列是 串行隊列 瓣履,那么將會 開啟 1 條線程 愿棋。
如果隊列具 **有開啟線程的能力 (隊列任務(wù)異步執(zhí)行) ** 且隊列是 并發(fā)隊列 ,那么將會 開啟 多 條線程 。開啟線程的條數(shù)由 GCD 決定托慨。
** ( 串行和并發(fā)決定的是開幾條線程 ) **

** 如果真正理解了上面這些治拿,多 GCD 的使用和面試基本沒什么障礙定罢。 **

2.1 全局隊列

全局隊列是獲取的族购,不是程序員創(chuàng)建的。
為了方便 GCD 的使用抵拘,apple 默認(rèn)為我們提供的哎榴。
全局隊列默認(rèn)是并發(fā)隊列,在不是進行第三方框架或者大型的商業(yè)應(yīng)用開發(fā),全局隊列基本夠用尚蝌。

全局 ( 并發(fā) ) 隊列異步執(zhí)行 :

并發(fā)隊列異步(不阻塞當(dāng)前線程)執(zhí)行(隊列就具有開啟線程的能力)迎变, 隊列會開啟多條線程。

任務(wù)異步執(zhí)行不會阻塞當(dāng)前線程飘言, 
   befor 在最前氏豌, 
   after 在任意位置,
   task 執(zhí)行順序不確定 —— 并發(fā)執(zhí)行(index可以確認(rèn))热凹。
   task 并發(fā)執(zhí)行 —— 并發(fā)執(zhí)行(number可以確認(rèn))。

異步開線程 number 可以確定開啟了多條線程
   開的線程數(shù)由 GCD 決定泪电。 可以看到線程的 number 有重復(fù)般妙,是 GCD 對線程進行了復(fù)用。
func async() {
    
    print("DispatchQueue.global().async: befor", Thread.current)
    // 全局隊列進行 10次異步
    for index in 0..<10 {

        DispatchQueue.global().async {
            print("DispatchQueue.global().async: task:(taskIndex:\(index)", Thread.current)
        }
    }
    print("DispatchQueue.global().async: after", Thread.current)
}

打酉嗨佟:
     DispatchQueue.global().async: befor <NSThread: 0x60800006a8c0>{number = 1, name = main}
     DispatchQueue.global().async: task:(taskIndex:1 <NSThread: 0x600000079780>{number = 3, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:2 <NSThread: 0x6000000797c0>{number = 4, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:0 <NSThread: 0x600000079880>{number = 5, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:3 <NSThread: 0x608000074e00>{number = 6, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:4 <NSThread: 0x600000079780>{number = 3, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:5 <NSThread: 0x6000000797c0>{number = 4, name = (null)}
     DispatchQueue.global().async: after <NSThread: 0x60800006a8c0>{number = 1, name = main}
     DispatchQueue.global().async: task:(taskIndex:6 <NSThread: 0x600000079880>{number = 5, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:7 <NSThread: 0x608000074e00>{number = 6, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:8 <NSThread: 0x600000079780>{number = 3, name = (null)}
     DispatchQueue.global().async: task:(taskIndex:9 <NSThread: 0x6000000797c0>{number = 4, name = (null)}

全局 ( 并發(fā) ) 隊列同步執(zhí)行 :

并發(fā)隊列同步(阻塞當(dāng)前線程)執(zhí)行(隊列就不具有開啟線程的能力)碟渺, 隊列不會開啟線程(代碼都在主線程中執(zhí)行)。

任務(wù)同步執(zhí)行會阻塞當(dāng)前線程突诬, 
     befor 在最前苫拍, 
     after 在最后,
     task 執(zhí)行順序確定 —— 阻塞旺隙。
同步?jīng)]有開啟線程 number 可以確定沒有開啟多條線程绒极。所有的代碼都在 主線程中執(zhí)行。
func sync() {
    print("DispatchQueue.global().sync: befor", Thread.current)
    for index in 0..<10 {
        DispatchQueue.global().sync {
            print("DispatchQueue.global().sync: task:(taskIndex:\(index))", Thread.current)
        }
    }
    print("DispatchQueue.global().sync: after", Thread.current)
}


打邮呓荨: 
DispatchQueue.global().sync: befor <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:0) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:1) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:2) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:3) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:4) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:5) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:6) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:7) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:8) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: task:(taskIndex:9) <NSThread: 0x60800007fa80>{number = 1, name = main}
DispatchQueue.global().sync: after <NSThread: 0x60800007fa80>{number = 1, name = main}

2.2 主隊列

主隊列是獲取的垄提,不是程序員創(chuàng)建的,apple 默認(rèn)為我們提供的周拐。
(app 開發(fā)中铡俐,所有的 UI 更新操作都應(yīng)該在主線程中進行)

主隊列(串行)異步執(zhí)行

主隊列異步(不會阻塞當(dāng)前線程)執(zhí)行(隊列就具有開啟線程的能力), 隊列會開啟線程(開啟的線程就是主線程)妥粟。

> 有朋友問我审丘,異步會開啟線程, 主隊列異步就不會開啟線程勾给。 
> 我當(dāng)時還信以為真滩报。認(rèn)為自己錯誤,說特殊情況特殊處理锦秒。 其實說白了就是學(xué)藝不精露泊。
> 由于主隊列是我們獲取的,不是我們創(chuàng)建的旅择,在某種意識中會認(rèn)為主線程不是在主隊列中創(chuàng)建的惭笑。(認(rèn)為一開始就存在的。)


> 任務(wù)異步執(zhí)行不會阻塞當(dāng)前線程, 
 befor 在最前沉噩, 
 after 在第二捺宗,
 task 執(zhí)行順序確定 —— 串行執(zhí)行(index可以確認(rèn))。

同步?jīng)]有開啟線程 number 可以確定沒有開啟多條線程川蒙。所有的代碼都在 主線程中執(zhí)行蚜厉。

主隊列異步的操作主要用在更新 UI 操作中。 具體參考 項目開發(fā)中 GCD 代碼使用畜眨。

func async() {
        
        print("DispatchQueue.main.async: befor", Thread.current)
        for index in 0..<10 {
            DispatchQueue.main.async {
                print("DispatchQueue.main.async: task:(taskIndex:\(index)", Thread.current)
            }
        }
        print("DispatchQueue.main.async: after", Thread.current)
}

打又缗!: 
DispatchQueue.main.async: befor <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: after <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:0 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:1 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:2 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:3 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:4 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:5 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:6 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:7 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:8 <NSThread: 0x60800006ddc0>{number = 1, name = main}
DispatchQueue.main.async: task:(taskIndex:9 <NSThread: 0x60800006ddc0>{number = 1, name = main}

主隊列(串行)同步執(zhí)行

執(zhí)行的效果就倆字 ** 死鎖**

主線程同步,在 Swift 中康聂,編譯階段就報錯贰健,在 oc 中是在運行的時候才能發(fā)現(xiàn)。體現(xiàn)的主要是界面的 “假死”恬汁。


Snip20170316_1.png

2.3 自定義隊列

/*
label:   隊列名稱
qos: 服務(wù)質(zhì)量
     // 后臺優(yōu)先級
     public static let background: DispatchQoS
    // 實用工具優(yōu)先級別(耗時操作伶椿,可以使用這個)
    public static let utility: DispatchQoS
    // 默認(rèn)優(yōu)先級(一般不是給程序員實用的,用來重置隊列用的)
    public static let `default`: DispatchQoS
    //  用戶期望優(yōu)先級(不要放太耗時的操作)
    public static let userInitiated: DispatchQoS
    // 用戶交互(希望盡快完成氓侧,用戶很希望得到結(jié)果脊另。個人覺得這個和主線的的線程優(yōu)先級是一樣的)
    public static let userInteractive: DispatchQoS
    // 未指定
    public static let unspecified: DispatchQoS


attributes: 隊列屬性
        // 并發(fā)
        public static let concurrent: DispatchQueue.Attributes
        // 初始化不活躍
        public static let initiallyInactive: DispatchQueue.Attributes

autoreleaseFrequency: 自動釋放頻率
          public enum AutoreleaseFrequency {
              // 繼承
              case inherit
              // 工作項
              case workItem
              // 從來沒有,永遠不
              case never
           }
  target: 目標(biāo)隊列

( 這些參數(shù)我也沒搞明白)
*/
public convenience init(label: String, 
                          qos: DispatchQoS = default, 
                   attributes: DispatchQueue.Attributes = default, 
         autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = default,
                       target: DispatchQueue? = default)

在沒有搞明白參數(shù)的時候约巷,由于 swift 可以使用默認(rèn)參數(shù)偎痛, 我們可以使用默認(rèn)參數(shù)。

自定義(串行)隊列異步執(zhí)行

// 使用默認(rèn)的構(gòu)造函數(shù)創(chuàng)建了一個隊列(并不知隊列是串行還是并發(fā))
// api 文檔沒有給夠足夠的信息载庭。 后期的文檔描述完整后可以直接查看文檔看彼。

func async() {
        
        print("DispatchQueue(label: \"laughing\").async: befor", Thread.current)
        let queue = DispatchQueue(label: "laughing")
        for index in 0..<10 {
            queue.async {
                print("DispatchQueue(label: \"laughing\").async: task:(taskIndex:\(index)", Thread.current)
            }
        }
        print("DispatchQueue(label: \"laughing\").async: after", Thread.current)
 }

      /*
         這么寫你會有一種串行隊列并發(fā)執(zhí)行的錯覺。
        for index in 0..<10 {
            DispatchQueue(label: "laughing").sync {
                print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
            }
        }
       */

打忧艟邸:
DispatchQueue(label: "laughing").async: befor <NSThread: 0x608000067180>{number = 1, name = main}
DispatchQueue(label: "laughing").async: after <NSThread: 0x608000067180>{number = 1, name = main}
DispatchQueue(label: "laughing").async: task:(taskIndex:0 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:1 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:2 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:3 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:4 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:5 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:6 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:7 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:8 <NSThread: 0x608000074200>{number = 3, name = (null)}
DispatchQueue(label: "laughing").async: task:(taskIndex:9 <NSThread: 0x608000074200>{number = 3, name = (null)}

** 由于只異步執(zhí)行只開了1 條線程靖榕, 可只。 默認(rèn)創(chuàng)建的隊列是 串行隊列**

自定義(串行)隊列同步執(zhí)行
串行隊列同步執(zhí)行顽铸,沒有開啟線程茁计。 代碼在主線程中執(zhí)行。

  func sync() {
        print("DispatchQueue(label: \"laughing\").sync: befor", Thread.current)
        
        let queue = DispatchQueue(label: "laughing")
        for index in 0..<10 {
            queue.sync {
                print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
            }
        }
        
        /*
         這么寫你會有一種串行隊列并發(fā)執(zhí)行的錯覺谓松。
        for index in 0..<10 {
            DispatchQueue(label: "laughing").sync {
                print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
            }
        }
        */
        
        print("DispatchQueue(label: \"laughing\").sync: after", Thread.current)
    }

打有茄埂: 
DispatchQueue(label: "laughing").sync: befor <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:0) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:1) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:2) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:3) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:4) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:5) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:6) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:7) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:8) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: task:(taskIndex:9) <NSThread: 0x600000071d40>{number = 1, name = main}
DispatchQueue(label: "laughing").sync: after <NSThread: 0x600000071d40>{number = 1, name = main}

自定義(并發(fā))隊列異步執(zhí)行
(參考全局隊列)

func async1() {
    
    print("DispatchQueue(label: \"laughing1\").async: befor", Thread.current)
    let queue = DispatchQueue(label: "laughing1",  attributes: DispatchQueue.Attributes.concurrent)
    for index in 0..<10 {
        queue.async {
            print("DispatchQueue(label: \"laughing1\").async: task:(taskIndex:\(index)", Thread.current)
        }
    }
    print("DispatchQueue(label: \"laughing1\").async: after", Thread.current)
}

打印
DispatchQueue(label: "laughing1").async: befor <NSThread: 0x600000261d80>{number = 1, name = main}
DispatchQueue(label: "laughing1").async: after <NSThread: 0x600000261d80>{number = 1, name = main}
DispatchQueue(label: "laughing1").async: task:(taskIndex:1 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:3 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:4 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:2 <NSThread: 0x60800026d9c0>{number = 4, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:5 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:7 <NSThread: 0x60800026d9c0>{number = 4, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:6 <NSThread: 0x60800026da00>{number = 5, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:0 <NSThread: 0x60800026db40>{number = 6, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:8 <NSThread: 0x60800026d380>{number = 3, name = (null)}
DispatchQueue(label: "laughing1").async: task:(taskIndex:9 <NSThread: 0x60800026d9c0>{number = 4, name = (null)}

自定義(并發(fā))隊列同步執(zhí)行

func sync1() {
    print("DispatchQueue(label: \"laughing1\").sync: befor", Thread.current)
    
    
    let queue = DispatchQueue(label: "laughing1",  attributes: DispatchQueue.Attributes.concurrent)
    for index in 0..<10 {
        queue.sync {
            print("DispatchQueue(label: \"laughing1\").sync: task:(taskIndex:\(index))", Thread.current)
        }
    }
    
    /*
     這么寫你會有一種串行隊列并發(fā)執(zhí)行的錯覺。
     for index in 0..<10 {
     DispatchQueue(label: "laughing").sync {
     print("DispatchQueue(label: \"laughing\").sync: task:(taskIndex:\(index))", Thread.current)
     }
     }
     */
    
    print("DispatchQueue(label: \"laughing1\").sync: after", Thread.current)
}


打印
DispatchQueue(label: "laughing1").sync: befor <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:0) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:1) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:2) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:3) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:4) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:5) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:6) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:7) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:8) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: task:(taskIndex:9) <NSThread: 0x608000061cc0>{number = 1, name = main}
DispatchQueue(label: "laughing1").sync: after <NSThread: 0x608000061cc0>{number = 1, name = main}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鬼譬,一起剝皮案震驚了整個濱河市娜膘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌优质,老刑警劉巖竣贪,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件军洼,死亡現(xiàn)場離奇詭異,居然都是意外死亡演怎,警方通過查閱死者的電腦和手機匕争,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來爷耀,“玉大人甘桑,你說我怎么就攤上這事〈醵#” “怎么了跑杭?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長咆耿。 經(jīng)常有香客問我艘蹋,道長,這世上最難降的妖魔是什么票灰? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮宅荤,結(jié)果婚禮上屑迂,老公的妹妹穿的比我還像新娘。我一直安慰自己冯键,他們只是感情好惹盼,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惫确,像睡著了一般手报。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上改化,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天掩蛤,我揣著相機與錄音,去河邊找鬼陈肛。 笑死揍鸟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的句旱。 我是一名探鬼主播阳藻,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼谈撒!你這毒婦竟也來了腥泥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤啃匿,失蹤者是張志新(化名)和其女友劉穎蛔外,沒想到半個月后蛆楞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡冒萄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年臊岸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尊流。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡帅戒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出崖技,到底是詐尸還是另有隱情逻住,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布迎献,位于F島的核電站瞎访,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吁恍。R本人自食惡果不足惜扒秸,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冀瓦。 院中可真熱鬧伴奥,春花似錦、人聲如沸翼闽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽感局。三九已至尼啡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間询微,已是汗流浹背崖瞭。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留撑毛,地道東北人读恃。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像代态,于是被迫代替她去往敵國和親寺惫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容