3、GCD-swift

GCD 一直以來(lái)是基于 c 語(yǔ)言的。
apple 為了使 GCD 使用更加的 swift 化。 對(duì) GCD 進(jìn)行了進(jìn)行了改造。
以下所有代碼都是基于 Swift3.0


先來(lái)段廢話:
(不了解基本概念的建議看看, 了解的直接略過(guò)!)

GCD

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

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

隊(duì)列

隊(duì)列是一種特殊的線性表,采用FIFO(先進(jìn)先出)的原則,即新任務(wù)總是被插入到隊(duì)列的末尾,而讀取任務(wù)的時(shí)候總是從隊(duì)列的頭部開(kāi)始讀取。每讀取一個(gè)任務(wù),則從隊(duì)列中釋放一個(gè)任務(wù)。

隊(duì)列的主要作用是用來(lái)存放任務(wù)。

GCD會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出,放到對(duì)應(yīng)的線程中執(zhí)行。

**隊(duì)列分類: **

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

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

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

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

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

常見(jiàn)隊(duì)列:

為了方便 GCD 使用,蘋果默認(rèn)提供了主隊(duì)列和全局隊(duì)列。 我們不需要?jiǎng)?chuàng)建只需要獲取。

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

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

任務(wù)

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

廢話到此完畢!


1. 項(xiàng)目開(kāi)發(fā)中 GCD 代碼使用

print("DispatchQueue.main.sync: befor", Thread.current)
DispatchQueue.global().async {
       print("DispatchQueue.global().async: Time task", Thread.current, "\n --: 耗時(shí)操作在后臺(tái)線程中執(zhí)行!")
            
      DispatchQueue.main.async {
          print("DispatchQueue.main.async: update UI", Thread.current, "\n --: 耗時(shí)操作執(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)} 
 --: 耗時(shí)操作在后臺(tái)線程中執(zhí)行!
DispatchQueue.main.async: update UI <NSThread: 0x60800007abc0>{number = 1, name = main} 
 --: 耗時(shí)操作執(zhí)行完畢后在主線程更新 UI 界面!

/*
 after 執(zhí)行的先后順序是不確定的。是由 GCD 決定。
這里牽扯到一個(gè)概念: 線程間通訊! 說(shuō)白的就是在線程間進(jìn)行數(shù)據(jù)(信號(hào))的傳遞。
*/

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


2. GCD 使用 —— 精講

先來(lái)了解 GCD 在 Swift 中的變化
GCD 框架頭文件改變

import Dispatch.base         // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.block        // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.data         // 沒(méi)有實(shí)質(zhì)性內(nèi)容
import Dispatch.group
import Dispatch.io
import Dispatch.object
import Dispatch.once        // 沒(méi)有實(shí)質(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 中所有的對(duì)象都間接的繼承自 NSObject。
import os_object
open class OS_object : NSObject {
}

Swift 中最大的變化其實(shí)就是更加的面相對(duì)象了,使用更加的方便簡(jiǎn)潔,擺脫了 OC 時(shí)代函數(shù)式的使用方式。

GCD 使用先來(lái)個(gè)個(gè)人小的總結(jié):

口訣:同步不開(kāi)異步開(kāi),串行開(kāi)1條,并行開(kāi)多條。

來(lái),跟著哥一起念。( 我怕你們打我,你們還是別念了,我解釋一下。)

同步不開(kāi)異步開(kāi),串行開(kāi)1條,并行開(kāi)多條。
單純這么簡(jiǎn)單的看是有誤解的, 在我的評(píng)論中就可以看到。

具體的意思是:
隊(duì)列中的任務(wù)同步執(zhí)行,隊(duì)列就不具有開(kāi)啟線程的能力, 隊(duì)列中的任務(wù)異步執(zhí)行,隊(duì)列就具有開(kāi)啟線程的能力。
(同步和異步執(zhí)行決定的是否有開(kāi)啟線程的能力)

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

** 如果真正理解了上面這些,多 GCD 的使用和面試基本沒(méi)什么障礙。 **

2.1 全局隊(duì)列

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

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

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

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

異步開(kāi)線程 number 可以確定開(kāi)啟了多條線程
   開(kāi)的線程數(shù)由 GCD 決定。 可以看到線程的 number 有重復(fù),是 GCD 對(duì)線程進(jìn)行了復(fù)用。
func async() {
    
    print("DispatchQueue.global().async: befor", Thread.current)
    // 全局隊(duì)列進(jìn)行 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ā) ) 隊(duì)列同步執(zhí)行 :

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

任務(wù)同步執(zhí)行會(huì)阻塞當(dāng)前線程, 
     befor 在最前, 
     after 在最后,
     task 執(zhí)行順序確定 —— 阻塞。
同步?jīng)]有開(kāi)啟線程 number 可以確定沒(méi)有開(kāi)啟多條線程。所有的代碼都在 主線程中執(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 主隊(duì)列

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

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

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

> 有朋友問(wèn)我,異步會(huì)開(kāi)啟線程, 主隊(duì)列異步就不會(huì)開(kāi)啟線程。 
> 我當(dāng)時(shí)還信以為真。認(rèn)為自己錯(cuò)誤,說(shuō)特殊情況特殊處理。 其實(shí)說(shuō)白了就是學(xué)藝不精。
> 由于主隊(duì)列是我們獲取的,不是我們創(chuàng)建的,在某種意識(shí)中會(huì)認(rèn)為主線程不是在主隊(duì)列中創(chuàng)建的。(認(rèn)為一開(kāi)始就存在的。)


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

同步?jīng)]有開(kāi)啟線程 number 可以確定沒(méi)有開(kāi)啟多條線程。所有的代碼都在 主線程中執(zhí)行。

主隊(duì)列異步的操作主要用在更新 UI 操作中。 具體參考 項(xiàng)目開(kāi)發(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}

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

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

主線程同步,在 Swift 中,編譯階段就報(bào)錯(cuò),在 oc 中是在運(yùn)行的時(shí)候才能發(fā)現(xiàn)。體現(xiàn)的主要是界面的 “假死”。


Snip20170316_1.png

2.3 自定義隊(duì)列

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


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

autoreleaseFrequency: 自動(dòng)釋放頻率
          public enum AutoreleaseFrequency {
              // 繼承
              case inherit
              // 工作項(xiàng)
              case workItem
              // 從來(lái)沒(méi)有,永遠(yuǎn)不
              case never
           }
  target: 目標(biāo)隊(duì)列

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

在沒(méi)有搞明白參數(shù)的時(shí)候,由于 swift 可以使用默認(rèn)參數(shù), 我們可以使用默認(rèn)參數(shù)。

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

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

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)
 }

      /*
         這么寫(xiě)你會(huì)有一種串行隊(duì)列并發(fā)執(zhí)行的錯(cuò)覺(jué)。
        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í)行只開(kāi)了1 條線程, 可只。 默認(rèn)創(chuàng)建的隊(duì)列是 串行隊(duì)列**

自定義(串行)隊(duì)列同步執(zhí)行
串行隊(duì)列同步執(zhí)行,沒(méi)有開(kāi)啟線程。 代碼在主線程中執(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)
            }
        }
        
        /*
         這么寫(xiě)你會(huì)有一種串行隊(duì)列并發(fā)執(zhí)行的錯(cuò)覺(jué)。
        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ā))隊(duì)列異步執(zhí)行
(參考全局隊(duì)列)

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ā))隊(duì)列同步執(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)
        }
    }
    
    /*
     這么寫(xiě)你會(huì)有一種串行隊(duì)列并發(fā)執(zhí)行的錯(cuò)覺(jué)。
     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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容