美文网首页
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