0
点赞
收藏
分享

微信扫一扫

iOS如何实现“多个异步操作结束后执行后续动作”

如何实现多个异步操作结束后执行后续动作

我们需要用到的一个核心的东西就是信号量: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 个任务上传)。
举报

相关推荐

0 条评论