簡體   English   中英

iOS 中的同步與異步隊列

[英]Sync vs Async Queue in iOS

我對 JS 有一些想法並且正在學習 iOS

我正在閱讀這個博客並且對 Swift 中的異步和同步感到困惑(盡管我覺得它在 IOS 和 Javascript 中是一樣的)但無論如何

import UIKit 

func smile () {
    print('1')
}

func love() {
    print('2')
}

//Serial Queue

let queue = DispatchQueue(label: 'SerialQueue')

queue.async {
    for _ in 1...5 {
     smile()
  }
}

 queue.async {
    for _ in 1...5 {
     love()
   }
 }

這將記錄類似這樣的內容 1

1
1
1
1
2
2
2
2
2

想想這個例子,如果是同步而不是異步,那么輸出會是一樣的嗎? 那么上面使用 async 有什么用呢?

另外,在 JS 中我們需要等待。 在 swift 中我們什么都不用做? 有人可以通過舉一個異步和等待的例子來向我解釋它嗎?

由於您對兩項工作使用相同的隊列,因此在第一個塊結束之前,第二個異步塊不會開始執行。 它是異步的還是串行的並不重要。

如果在兩個隊列之間添加打印語句,您將看到.async.sync之間的真正區別。 像這樣:

queue.async {
    for _ in 1...100 {
          self.smile()
    }
}
print("Finished printing smiles")
queue.async {
    for _ in 1...100 {
          self.love()
    }
}

前面的代碼可能會在開始打印微笑之前打印“完成打印微笑”! 那是因為異步工作會立即返回並繼續執行代碼。


讓我們看看如果使用同步隊列更改隊列會發生什么:

queue.sync {
    for _ in 1...100 {
          self.smile()
    }
}
print("Finished printing smiles")
queue.sync {
    for _ in 1...100 {
          self.love()
    }
}

是的。 現在同步隊列在關閉完成之前等待,然后再繼續。 所以,你會得到 100 個微笑,然后是“完成打印的微笑”。


如果你想達到的並發,就是這樣,(在完全相同的時間,但沒有,因為那將是並行)同時執行的代碼兩大塊,你必須使用兩個不同的隊列,或指定.concurrent在參數隊列配置:

override func viewDidLoad() {

    let queue = DispatchQueue(label: "SerialQueue")
    let queue2 = DispatchQueue(label: "AnotherQueue")

    queue.async {
        for _ in 1...100 {
              self.smile()
        }
    }
    print("Finished printing smiles")
    queue2.async {
        for _ in 1...100 {
              self.love()
        }
    }
}

正如您將看到的,這里的順序是混亂的,並且會因執行而異。 那是因為兩個隊列同時運行。

另一個與此代碼等效的代碼是:

let queue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)

queue.async {
    for _ in 1...100 {
          self.smile()
    }
}
print("Finished printing smiles")
queue.async {
    for _ in 1...100 {
          self.love()
    }
}

@loufranco 和@Roberto 已詳細回答。

您還可以在單​​個OperationQueue添加不同的BlockOperation來實現此目的。

好像你會在這個場景中看到:

let queue = OperationQueue()

let operation1 = BlockOperation {
    for _ in 1...5 {
     smile()
  }
}
print("Done")
let operation2 = BlockOperation {
    for _ in 1...5 {
     love()
   }
 }

queue.addOperation (operation1)
queue.addOperation (operation2)

輸出是:

在此處輸入圖片說明

如果您將在 operation1 上添加 operation2 依賴項:

operation2.addDependency(operation1)
queue.addOperation (operation1)
queue.addOperation (operation1)

輸出是:

在此處輸入圖片說明

當您使用同步時,它在隊列的線程中執行,但同步在完成之前不會返回。 異步立即返回。

因為你有一個串行隊列,打印是一樣的,但調用函數可以在隊列完成打印之前返回。 如果它是同步的,調用函數將等待打印完成。

Swift 中還沒有 async/await 概念。 這不是這里發生的事情(或在同步情況下)

如果您想查看差異,請將 sleeps 放入塊中並在隊列調用之外打印。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM