在開發(fā)中對于多個網(wǎng)絡請求下的數(shù)據(jù)處理屯阀,一般會碰到以下兩種需求:
- A網(wǎng)絡請求完成救欧,再進行B網(wǎng)絡請求值戳,最后數(shù)據(jù)處理
- A網(wǎng)絡請求與B網(wǎng)絡請求完成之后,最后數(shù)據(jù)處理
第一種場景:
場景例子: A網(wǎng)絡請求獲取臨時token愈腾,用于B網(wǎng)絡請求的參數(shù)
處理方式:
- (void)sceneOneTest {
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// 獲取token
NSString *tempToken = ...;
[[NetworkEngine shareEngine] fetch... requestParamter:@{@"token": tempToken} completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
// Todo
}];
} else {
// 異常處理
}
}];
}
注意點:
- 異常處理
- 多個網(wǎng)絡請求時候封裝
- 循環(huán)引用
第二種場景:
場景例子:A網(wǎng)絡請求 和 B網(wǎng)絡請求完成后憋活,刷新界面(一般用于數(shù)據(jù)量大業(yè)務區(qū)分明顯的頁面)
處理方法A:使用一個計數(shù)變量,來統(tǒng)計網(wǎng)絡請求的完成數(shù)量
static char *blockKey;
- (void)sceneTwoTestA {
__block NSInteger networkFinishNum = 0;
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
void(^block)() = objc_getAssociatedObject(self, blockKey);
if (block) {
block();
}
} else {
// 異常處理
}
}];
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
void(^block)() = objc_getAssociatedObject(self, blockKey);
if (block) {
block();
}
} else {
// 異常處理
}
}];
void(^completionBlock)() = ^{
networkFinishNum ++;
if (networkFinishNum == 2) {
// 刷新界面
}
};
objc_setAssociatedObject(self, blockKey, completionBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
處理方法B:通過GCD的信號量虱黄,完成場景需求
- (void)sceneTwoTestB {
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 執(zhí)行循序1
dispatch_group_async(group, queue, ^{
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 異常處理
}
// 執(zhí)行順序4/6
dispatch_semaphore_signal(semaphore);
}];
});
// 執(zhí)行循序2
dispatch_group_async(group, queue, ^{
[[NetworkEngine shareEngine] fetch... completionBlock:^(BOOL isSucceeded, id responseObject, NSError *error) {
if (isSucceeded) {
// Todo
} else {
// 異常處理
}
// 執(zhí)行順序4/6
dispatch_semaphore_signal(semaphore);
}];
});
dispatch_group_notify(group, queue, ^{
// 執(zhí)行循序3
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 執(zhí)行順序5
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 執(zhí)行順序7
dispatch_async(dispatch_get_main_queue(), ^{
// 刷新界面
});
});
}
簡單的介紹一下關于信號量的三個方法:
信號量可以用車庫中的空閑車位來表示悦即,當往車庫停車時候,如果車庫已滿橱乱,則需等待(阻塞線程)
1.創(chuàng)建一個車庫辜梳,value表示車庫中空閑車位的數(shù)量
dispatch_semaphore_create(long value);
2.往車庫里面停一輛車,如果沒有空車位泳叠,則一直會等待在車庫外作瞄,等待時間為dispatch_time_t timeout,如果有空車位則停車危纫,減少一個空車位
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
3.從車庫中開走一輛車,增加一個空閑車位
dispatch_semaphore_signal(dispatch_semaphore_t dsema);