线程与线程组
线程是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_enter 和 dispatch_group_leave 这两个方法一定要配合使用,否则 dispatch_group_notify 是不会执行的。
最后,祝各位小伙伴代码敲得愉快!