如何实现多个异步操作结束后执行后续动作
我们需要用到的一个核心的东西就是信号量:DispatchSemaphore
首先介绍下信号量
的基本语法
初始化
swift
let sema = DispatchSemaphore.init(value: 0)
oc
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
可以看出,我们传了一个 Int 值用于初始化信号量。
两个核心方法
swift
//等待
sema.wait()
//完成
sema.signal()
oc
//等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
//完成
dispatch_semaphore_signal(sema);
wait
会对信号量 -1, -1后,如果信号量<0,则会阻塞线程
signal
会对信号量 +1
接着让我们看下信号量
的简单用法
1、单任务实例
以 swift 为例
//1
DispatchQueue.global().async {
//2
let sema = DispatchSemaphore.init(value: 0)
//3
NetManager.shared().checkPermission(withSpace: model.spaceType, andParentID: parentId, andChildenID: [modid], andAction: "copyFile2All", success: { (result) in
//4
sema.signal()
}) { (msg) in
//4
sema.signal()
}
//5
sema.wait()
//6
}
如上所示,我们可以在 注释6
的位置写上我们需要执行的代码。便达到了通过信号量等待一个任务完成后,执行下一个任务的要求。
2、多任务实例
DispatchQueue.global().async {
let sema = DispatchSemaphore.init(value: 0)
for i in self.selectedItems {
NetManager.shared().checkPermission(withSpace: model.spaceType, andParentID: parentId, andChildenID: [modid], andAction: "copyFile2All", success: { (result) in
self.performSegue(withIdentifier: "showDirectoryTreevcID", sender: "copy")
sema.signal()
}) { (msg) in
//
sema.signal()
}
}
for _ in self.selectedItems {
sema.wait()
}
//刷新 UI 等操作可以放在这里(注:如果是对 UI 操作要放在主线程哦)
}
通过单任务实例
理解这个多任务的实例应该不难,在此不多做赘述。
总结
- 上例中的网络请求方法只是实例用的,读者可以自己写个网络请求替换掉
- 信号量有三个比较关键的点(信号量的值,wait 方法,signal 方法),理解透了用起来很简单,且好用
- 信号量的初始化的值在本例中为 0,如果是正整数,一般用于多任务线程池(比如同时最大支持n 个任务上传)。