Mic*_*ael 7 grand-central-dispatch ios swift
(或许通过串行调度队列如何保证资源保护来回答?但我不明白如何)
题
gcd如何知道异步任务(例如网络任务)何时完成?我应该使用dispatch_retain并dispatch_release为此目的吗?更新:我不能用ARC调用这些方法中的任何一个......怎么办?
细节
我正在与进行大量网络访问的第三方库进行交互.我已经通过一个小类创建了一个包装器,它基本上提供了我需要的所有方法来自第三方类,但包装调用dispatch_async(serialQueue) { () -> Void in(其中serialQueue是我的包装类的成员).
我试图确保每个对底层库的调用在下一次开始之前完成(某种程度上,它尚未在库中实现).
Pau*_*w11 14
串行调度队列上的工作序列化是在直接提交给队列的工作单元上.一旦执行到达提交的闭包的末尾(或它返回),则可以执行队列上的下一个工作单元.
重要的是,闭包可能已经启动的任何其他异步任务可能仍在运行(或者甚至可能尚未开始运行),但不考虑它们.
例如,对于以下代码:
dispatch_async(serialQueue) {
print("Start")
dispatch_async(backgroundQueue) {
functionThatTakes10Seconds()
print("10 seconds later")
}
print("Done 1st")
}
dispatch_async(serialQueue) {
print("Start")
dispatch_async(backgroundQueue) {
functionThatTakes10Seconds()
print("10 seconds later")
}
print("Done 2nd")
}
Run Code Online (Sandbox Code Playgroud)
输出将是这样的:
开始
完成第1
开始
完成第二
10秒后
10秒后
请注意,在调度第二个串行任务之前,前10秒任务尚未完成.现在,比较:
dispatch_async(serialQueue) {
print("Start")
dispatch_sync(backgroundQueue) {
functionThatTakes10Seconds()
print("10 seconds later")
}
print("Done 1st")
}
dispatch_async(serialQueue) {
print("Start")
dispatch_sync(backgroundQueue) {
functionThatTakes10Seconds()
print("10 seconds later")
}
print("Done 2nd")
}
Run Code Online (Sandbox Code Playgroud)
输出将是这样的:
开始
10秒后
完成第1
开始
10秒后
完成第二
请注意,这次是因为同步调度了10秒的任务,所以串行队列被阻止,第二个任务在第一个任务完成之前没有启动.
在您的情况下,您正在包装的操作很可能会自己调度异步任务(因为这是网络操作的本质),因此串行调度队列本身是不够的.
您可以使用a DispatchGroup来阻止串行调度队列.
dispatch_async(serialQueue) {
let dg = dispatch_group_create()
dispatch_group_enter(dg)
print("Start")
dispatch_async(backgroundQueue) {
functionThatTakes10Seconds()
print("10 seconds later")
dispatch_group_leave(dg)
}
dispatch_group_wait(dg)
print("Done")
}
Run Code Online (Sandbox Code Playgroud)
这将输出
开始
10秒后
完成
该dg.wait()块串行队列中,直到数量dg.leave调用相匹配的数量dg.enter调用.如果您使用此技术,则需要小心确保包装操作调用的所有可能的完成路径dg.leave.还有一些变量dg.wait()采用超时参数.
| 归档时间: |
|
| 查看次数: |
3793 次 |
| 最近记录: |