美文网首页SwiftiOS-多线程面试合集
iOS如何实现“多个异步操作结束后执行后续动作”

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

作者: 本帅不良 | 来源:发表于2020-12-11 15:42 被阅读0次

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

    场景:我们可能对列表中的数据进行批量操作后,执行下一步操作。如多选删除后,刷新页面;如多选下载后,提示下载完成。

    我们需要用到的一个核心的东西就是信号量: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
    }           
    

    代码解读:

    1. wait 方法会阻塞主线程,所以需要放在子线程中,本例放在 global 中
    2. 创建信号量对象,信号量为 0
    3. 网络请求的任务,使用的是AFNetworking
    4. 任务完成,信号量+1
    5. 信号量首先-1,然后检测信号的值。当信号量<0时阻塞,并一直检测信号量变化,直到信号量>0时,便会往后执行,
    • 注意:使用信号量,一定要放在子线程中,否则主线程会一直阻塞。

    如上所示,我们可以在 注释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 个任务上传)。

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/nqpjgktx.html