iOS中的同步与异步队列
Posted
技术标签:
【中文标题】iOS中的同步与异步队列【英文标题】:Sync vs Async Queue in iOS 【发布时间】:2020-02-03 13:14:22 【问题描述】:我对 JS 有一些想法,并且正在使用 ios
我正在阅读 this blog 并且对 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 中我们需要等待。迅速我们不需要做任何事情?有人可以通过快速给出异步和等待的例子来向我解释吗?
【问题讨论】:
我认为你会受益于更多地研究 async/await(如在 javascript 中看到的,以及在其他语言中看到的),并准确地了解它的作用。 【参考方案1】:由于您对两个作品使用相同的队列,因此第二个异步块在第一个块结束之前不会开始执行。不管是异步的还是串行的。
如果您在两个队列之间添加打印语句,您将看到.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 个微笑,然后是“完成打印的微笑”。
如果你想实现并发,就是这样,两个代码块同时执行(但不完全相同,因为那将是并行性),你必须使用两个不同的队列,或者指定@987654325队列配置中的@参数:
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()
【讨论】:
【参考方案2】:@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)
输出是:
【讨论】:
【参考方案3】:当您使用同步时,它会在队列的线程中执行,但同步在完成之前不会返回。 async 立即返回。
因为你有一个串行队列,所以打印是一样的,但是调用函数可以在队列完成打印之前返回。如果它是同步的,则调用函数将等待打印完成。
Swift 中还没有 async/await 的概念。这不是这里发生的事情(或在同步情况下)
如果您想查看差异,请将 sleep 放入块中并在队列调用之外打印。
【讨论】:
以上是关于iOS中的同步与异步队列的主要内容,如果未能解决你的问题,请参考以下文章
GCD使用 串行并行队列 与 同步异步执行的各种组合 及要点分析
# 进程/线程/协程 # IO:同步/异步/阻塞/非阻塞 # greenlet gevent # 事件驱动与异步IO # SelectPollEpoll异步IO 以及selectors模块 # (示