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

你可能感兴趣的:(iOS之线程组实现页面刷新)