美文网首页
dispatch group

dispatch group

作者: 闭家锁 | 来源:发表于2018-01-30 23:26 被阅读27次

    dispatch group

    有时候我们会有这种需求,在刚进去一个页面需要发送两个请求,并且某种特定操作必须在两个请求都结束(成功或失败)的时候才会执行,最low的办法第二个请求嵌套在第一个请求结果后在发送,在第二个请求结束后再执行操作。还有就是只使用一个Serial

    Dispatch Queue,把想要执行的操作全部追加到这个Serial Dispatch

    Queue中并在最后追加某种特定操作,颇为复杂操作。但是呢,我们这里介绍更高级的办法使用dispatch group。

    我们将ABC三个任务block追加到Global Dispatch Queue,ABC全部执行完,会执行dispatch_group_notify中的block。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

    dispatch_group_t  group = dispatch_group_creat();

    dispatch_group_async(group,queue,^{执行任务A});

    dispatch_group_async(group,queue,^{执行任务B});

    dispatch_group_async(group,queue,^{执行任务C});

    dispatch_group_notify(group,dispatch_get_main_queue(),^{执行最终的特定操作});

    ABC的执行顺序不固定,因为是Global Dispatch Queue即Concurrent Dispatch Queue多个现场并行执行。

    上面的dispatch_group_notify(group,dispatch_get_main_queue(),^{执行最终的特定操作});操作还可以更改为

    dispatch_group_wait(group,DISPATCH_TIME_FOREVER);

    dispatch_group_wait第二个参数指定为等待的时间(超时),属于dispatch_time_t类型,在这里使用DISPATCH_TIME_FOREVER,意味着永久等待。如果dispatch group的处理尚未结束,就会一直等待。

    如果指定等待时间为1秒如下:

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull * NESC_PER_SEC);

    long result = dispatch_group_wait(group,time);

    if(result == 0) { dispatch group的全部处理执行结束}

    else { dispatch groupe的某一处理还在执行中};

    但是呢上面这种dispatch_group的排列执行方式,是不会考虑block块内部的异步请求情况的,它只能保证把block内的非异步直观代码执行完,所以如果ABC三个任务中如果有执行异步的请求,那么在dispatch_group_notify最终任务执行中,那个异步请求不一定毁掉结束。

    在这里给大家介绍针对这种问题另一个API。

    dispatch_group_enter/dispatch_group_leave

    dispatch_group_t group = disoatch_group_creat();

    dispatch_group_enter(group);

    dispatch_async(dispath_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

    //在这里执行异步请求A

    并且在执行结束代码(成功或失败)中写上dispatch_group_leave(group);

    });

    dispatch_async(dispath_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

    //在这里执行异步请求B

    并且在执行结束代码(成功或失败)中写上dispatch_group_leave(group);

    });

    dispatch_group_notify(group,dispatch_get_main_queue(),^{执行最终的特定操作});

    上面这种做法当执行到dispatch_group_notify,一定是AB两个异步请求都加在结束了。dispatch_group_enter(group)和dispatch_group_leave(group);必须成对出现,编译器会强制识别当出现dispatch_group_leave全部结束才执行dispatch_group_notify,即使这种,档异步执行了AB两个请求,也不能保证请求执行结束的先后顺序,如果任务B的请求参数包含请求A的返回参数,那么只能用最Low的办法将请求B嵌套在A中执行,当然如果你有更好的办法欢迎提出来哈。

    最近的项目正好有多个请求并发执行,但需要返回所有请求的结果之后,再更新界面的需求,正好用到dispatch group,还比较满足需求,但是碰到任务B的请求参数包含请求A的返回参数这种情况也有可能,还真是需要找一个优雅的姿势解决这种情况。

    转自:http://www.cocoachina.com/ios/20160804/17291.html

    相关文章

      网友评论

          本文标题:dispatch group

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