3、GCD-swift

GCD 一直以來是基于 c 語言的。
apple 為了使 GCD 使用更加的 swift 化。 對 GCD 進(jìn)行了進(jìn)行了改造。
以下所有代碼都是基于 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 中兩個重要重要概念 —— 隊(duì)列 & 任務(wù)

隊(duì)列

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

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

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

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

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

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

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

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

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

常見隊(duì)列:

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

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

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

任務(wù)

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

廢話到此完畢!


1. 項(xiàng)目開發(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 決定。
這里牽扯到一個概念: 線程間通訊! 說白的就是在線程間進(jìn)行數(shù)據(jù)(信號)的傳遞。
*/

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


2. GCD 使用 —— 精講

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

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

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

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

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

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

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

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

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

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

2.1 全局隊(duì)列

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

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

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

任務(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 對線程進(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ì)列就不具有開啟線程的能力), 隊(duì)列不會開啟線程(代碼都在主線程中執(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 主隊(duì)列

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

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

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

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


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

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

主隊(duì)列異步的操作主要用在更新 UI 操作中。 具體參考 項(xiàng)目開發(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 中,編譯階段就報錯,在 oc 中是在運(yùn)行的時候才能發(fā)現(xiàn)。體現(xiàn)的主要是界面的 “假死”。


Snip20170316_1.png

2.3 自定義隊(duì)列

/*
label:   隊(duì)列名稱
qos: 服務(wù)質(zhì)量
     // 后臺優(yōu)先級
     public static let background: DispatchQoS
    // 實(shí)用工具優(yōu)先級別(耗時操作,可以使用這個)
    public static let utility: DispatchQoS
    // 默認(rèn)優(yōu)先級(一般不是給程序員實(shí)用的,用來重置隊(duì)列用的)
    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: 隊(duì)列屬性
        // 并發(fā)
        public static let concurrent: DispatchQueue.Attributes
        // 初始化不活躍
        public static let initiallyInactive: DispatchQueue.Attributes

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

( 這些參數(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ù)。

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

// 使用默認(rèn)的構(gòu)造函數(shù)創(chuàng)建了一個隊(duì)列(并不知隊(duì)列是串行還是并發(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)
 }

      /*
         這么寫你會有一種串行隊(duì)列并發(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)建的隊(duì)列是 串行隊(duì)列**

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

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

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