美文网首页iOS那些坑iOS Developer程序员
iOS之线程组实现页面刷新

iOS之线程组实现页面刷新

作者: Cocoaleeo | 来源:发表于2017-03-30 22:17 被阅读336次

    线程与线程组

    线程是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 是不会执行的。
    最后,祝各位小伙伴代码敲得愉快!

    相关文章

      网友评论

        本文标题:iOS之线程组实现页面刷新

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