美文网首页
dispatch_group的使用

dispatch_group的使用

作者: 12345qwert | 来源:发表于2018-08-03 15:46 被阅读6次

    前言

    使用dispatch_group过程中,如果发现以下问题:

    • crash:leave次数 > enter次数
    • notify的block没有回调:leave次数 < enter次数
      总之,一定要保证leave和enter的次数相等。

    使用场景

    多个sevice并发执行,等获取到所有的数据后进行UI刷新。

    使用方法

    为了方便说明,约定如下:

    • 处理多个service的类为:ServiceHandler
    • 在ServiceHandler的fetchDataWithFinishBlock:方法中去做统一的网络请求和dispatch_group_notify的调用。

    注意点:

    • 确保在ServiceHandler里只有一个group
    • 在serviceDidStartLoadBlock里做enter
    • 在serviceDidFinishLoadBlock和serviceDidFailLoadBlock里做leave

    于是,代码大致是这样子的:

     - (void)fetchDataWithBlock:(ServiceCallBack)finishBlock {
            [service1 getData];
            [service2 getData];
            [service3 getData];
           
            dispatch_group_notify(_group, dispatch_get_main_queue(), ^{
                finishBlock(xxx);
            });
        }
    
    - (Service *)service1{
        if (_service1 == nil) {
           _service1 = [[HYUserLevelService alloc] init];
            WEAKSELF
            _service1.serviceDidStartLoadBlock = ^(WeAppBasicService *service) {
                StrongSelf
                dispatch_group_enter(strongSelf.group);
            };
            _service1.serviceDidFinishLoadBlock = ^(WeAppBasicService *service) {
                STRONGSELF
                dispatch_group_leave(strongSelf.group);
            };
            _service1.serviceDidFailLoadBlock = ^(WeAppBasicService *service, NSError *error) {
                STRONGSELF
                NSString* errorMsg = [(KSAdapterService*)service message];
                EHLogError(@"err code = %@, err message = %@", [(KSAdapterService*)service code], errorMsg);
                dispatch_group_leave(strongSelf.group);
            };
        }
        return _service1;
    }
    

    代码说明

    在实际使用中,fetchDataWithBlock:可能会被多次调用,而且前后两次调用的时间间隔很短。

    • 确保group只有一个:举个例子,如果多次调用中group发生变化,而网络请求又比较慢,会存在第一次网络请求成功后调用dispatch_group_leave时的group已经变成了第二次的group。

    • dispatch_group_enter(group)放到serviceDidStartLoadBlock中,可以比较好的解决可能出现的leave和enter的次数不相等的问题。

    • fetchDataWithBlock:调用多次后notify的block也会回调多次。即使前后调用fetchDataWithBlock:的时间间隔很短(这样service的serviceDidStartLoadBlock和serviceDidFinishLoadBlock只会调用一次)。原因是:多个block被注册到了dispatch_group_notify中,等enter和leave相等时会统一将这些block回调。这里可以根据自己的业务逻辑去处理这些回调是否全部需要。

    相关文章

      网友评论

          本文标题:dispatch_group的使用

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