場(chǎng)景要求:要求請(qǐng)求A和請(qǐng)求B都都完成拿到結(jié)果,再執(zhí)行C操作。
目前發(fā)現(xiàn)比較好的處理方法,共有三種,歡迎簡(jiǎn)友補(bǔ)充。
第一種方法:利用NSOperation
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
// 異步發(fā)送請(qǐng)求A,得到結(jié)果
NSLog(@"%s****當(dāng)前線程:%@ 結(jié)果A",__func__,[NSThread currentThread]);
}];
NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
// 異步發(fā)送請(qǐng)求,得到結(jié)果
NSLog(@"%s****當(dāng)前線程:%@ 結(jié)果B",__func__,[NSThread currentThread]);
}];
// [queue addOperation:operationA];
// [queue addOperation:operationB]; // 此處會(huì)先執(zhí)行NSlog ,再執(zhí)行block(不滿足項(xiàng)目要求)
[queue addOperations:@[operationA,operationB] waitUntilFinished:YES]; // 此處會(huì)等待opertionA和B執(zhí)行完畢,再執(zhí)行NSLOG
NSLog(@"執(zhí)行到這里了么");
打印結(jié)果是:2016-12-08 11:16:46.490 testU[12234:249618] __37-[ViewController userOperationMethod]_block_invoke****當(dāng)前線程:<NSThread: 0x7fd508715a20>{number = 3, name = (null)} 結(jié)果A
2016-12-08 11:16:46.490 testU[12234:249628] __37-[ViewController userOperationMethod]_block_invoke_2****當(dāng)前線程:<NSThread: 0x7fd5086022b0>{number = 2, name = (null)} 結(jié)果B
2016-12-08 11:16:46.490 testU[12234:249458] 執(zhí)行到這里了么
第二種方法 :利用RAC
- (void)userRACMethod
{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 異步請(qǐng)求,得到結(jié)果resultA
NSLog(@"%s****當(dāng)前線程:%@ 結(jié)果A",__func__,[NSThread currentThread]); // 位于主線程 = 1
[subscriber sendNext:@{@"value":@"resultA"}];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 異步請(qǐng)求,得到結(jié)果resultB
NSLog(@"%s****當(dāng)前線程:%@ 結(jié)果B",__func__,[NSThread currentThread]); // 位于主線程 = 1
[subscriber sendNext:@{@"haha":@"resultB"}];
return nil;
}];
[self rac_liftSelector:@selector(updateUIWithResultA:ResultB:) withSignalsFromArray:@[signalA,signalB]];
}
- (void)updateUIWithResultA:(NSDictionary *)resultA ResultB:(NSDictionary *)resultB
{
NSLog(@"刷新頁面數(shù)據(jù)%@\n%@",resultA,resultB);
// 拿到上述A,B結(jié)果,執(zhí)行其他操作 ......
}
第三種方法:利用隊(duì)列組
// *** 利用隊(duì)列組 ****//
- (void)userGroupMethod
{
// 創(chuàng)建隊(duì)列組
dispatch_group_t myGroup = dispatch_group_create();
// 創(chuàng)建并發(fā)隊(duì)列
dispatch_queue_t myQueue = dispatch_queue_create(0, 0);
// 使用函數(shù)添加任務(wù)(所有任務(wù)都是并發(fā)執(zhí)行)
/**
* 任務(wù)A
*/
dispatch_group_enter(myGroup);
dispatch_async(myQueue, ^{
// 請(qǐng)求A
if (success) {
// 請(qǐng)求成功
dispatch_group_leave(myGroup);
}else{
// 失敗
dispatch_group_leave(myGroup);
}
});
/**
* 任務(wù)B
*/
dispatch_group_enter(myGroup);
dispatch_async(myQueue, ^{
// 請(qǐng)求B
if (success) {
// 請(qǐng)求成功
dispatch_group_leave(myGroup);
}else{
// 失敗
dispatch_group_leave(myGroup);
}
});
// A,B執(zhí)行完畢,不論成功失敗。只要執(zhí)行完畢就執(zhí)行下方代碼
dispatch_group_notify(myGroup, myQueue, ^{
// 執(zhí)行C操作。注意刷新UI等需要回到主線程。
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新等操作。
});
});
}
歡迎指正添加。接下來還要抽出一部分時(shí)間專門研究下多線程,感覺多線程真是博大精深。