iOS之线程组实现页面刷新

线程与线程组

线程是iOS开发进阶必经之路,不会多线程,那你一定不是一个合格的iOSer。

多线程基础看这里:关于iOS多线程,你看我就够了

这篇文章只讲一个问题,在开辟了多个线程之后如何在各个子线程都完成后进行主线程刷新。

例如,一个页面上需要展示几部分内容,但这几部分需要调用多个网络请求来完成,如果挨个调用,在每个请求完成后进行界面刷新,倒是也可以,但是对于强迫症重度患者来说,我就想在拿到数据后一次刷新,怎么搞!

代码先来两段:

用到的Block
typedef void (^GET_USERINFO)(BOOL result, id responseObj);
Method1
+ (void)qw_getMyinfo:(GET_USERINFO)result
{
    dispatch_group_t groupQueue = dispatch_group_create();
    dispatch_queue_t networkQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSMutableDictionary *resultDic = [[NSMutableDictionary alloc]init];
   [NetManager qw_getUserInfomationResult:^(BOOL result, id responseObj) {
        if (result) {
            dispatch_group_async(groupQueue, networkQueue, ^{
                [resultDic setObject:responseObj forKey:@"Info"];
            });
        }
    }];
    [NetManager qw_getExchangeCount:^(BOOL result, id responseObj) {
        if (result) {
            dispatch_group_async(groupQueue, networkQueue, ^{
                [resultDic setObject:responseObj forKey:@"Exchange"];
            });
        }
    }];
    dispatch_group_notify(groupQueue, dispatch_get_main_queue(), ^{
        result(YES, resultDic);
    });
}
Method2
+ (void)qw_getMyinfo:(GET_USERINFO)result
{
    dispatch_group_t groupQueue = dispatch_group_create();
    dispatch_queue_t networkQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSMutableDictionary *resultDic = [[NSMutableDictionary alloc]init];
    dispatch_group_async(groupQueue, networkQueue, ^{
        [NetManager qw_getUserInfomationResult:^(BOOL result, id responseObj) {
            if (result) {
                 [resultDic setObject:responseObj forKey:@"Info"];
            }
        }];
    });
    dispatch_group_async(groupQueue, networkQueue, ^{
        [NetManager qw_getExchangeCount:^(BOOL result, id responseObj) {
        if (result) {
            [resultDic setObject:responseObj forKey:@"Exchange"];
        }
    }];
    });
    dispatch_group_notify(groupQueue, dispatch_get_main_queue(), ^{
        result(YES, resultDic);
    });
}

为什么这两个方法无效呢???
实际上这两个方法是有效的,只不过没有达到我们所需要的效果而已;
method1中将队列添加到线程组中是在网络请求完成之后的,所以这里的顺序就成了 notify -> networkQueue!
method2中是将网络请求的操作放到了队列中,但是对网络请求的结果就直接无视了。
原因来啦:我们都知道网络请求中会开辟新的线程来进行操作,在上面的方法中,我们创建的队列实际上是与网络请求中的线程是脱节的,也就是说网络请求开辟的线程并没有放到线程组中,那么怎样在两者之间建立链接呢,请看method3。

Method3(有效)
+ (void)qw_getMyinfo:(GET_USERINFO)result
{
    dispatch_group_t groupQueue = dispatch_group_create();
    NSMutableDictionary *resultDic = [[NSMutableDictionary alloc]init];
    dispatch_group_enter(groupQueue);
    [NetManager qw_getUserInfomationResult:^(BOOL result, id responseObj) {
        if (result) {
            [resultDic setObject:responseObj forKey:@"Info"];
        }
        dispatch_group_leave(groupQueue);
    }];
    dispatch_group_enter(groupQueue);
    [NetManager qw_getExchangeCount:^(BOOL result, id responseObj) {
        if (result) {
            [resultDic setObject:responseObj forKey:@"Exchange"];
        }
        dispatch_group_leave(groupQueue);
    }];
    dispatch_group_notify(groupQueue, dispatch_get_main_queue(), ^{
        result(YES, resultDic);
    });
}

这样就可以将网络请求中所开辟的线程放入到线程组中,值得注意的是 dispatch_group_enterdispatch_group_leave 这两个方法一定要配合使用,否则 dispatch_group_notify 是不会执行的。
最后,祝各位小伙伴代码敲得愉快!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 担心了两周的我终于轮到去医院做胃镜检查了!去的时候我都想好了最坏的可能(胃癌),之前在网上查的症状都很相似。...
    Dely阅读 13,030评论 21 42
  • 多线程 在iOS开发中为提高程序的运行效率会将比较耗时的操作放在子线程中执行,iOS系统进程默认启动一个主线程,用...
    郭豪豪阅读 7,404评论 0 4
  • 从哪说起呢? 单纯讲多线程编程真的不知道从哪下嘴。。 不如我直接引用一个最简单的问题,以这个作为切入点好了 在ma...
    Mr_Baymax阅读 7,789评论 1 17
  • ##abc
    b0133329f849阅读 3,538评论 0 51
  • 作为一枚彻头彻尾的吃货+一枚有良心的 葡萄酒生活 公号小编 ,我每天最重要的事情就是“吃喝”以及看别人“吃喝” !...
    乐小饮阅读 3,339评论 0 3