一讳苦、處理高并發(fā)請求的核心代碼如下:
// 創(chuàng)建信號量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 創(chuàng)建全局并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
// 請求
[self httpRequest];
dispatch_semaphore_signal(semaphore);
});
dispatch_group_notify(group, queue, ^{
// 請求對應信號等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
分析:
首先創(chuàng)建并行隊列,創(chuàng)建隊列組,將隊列和需要處理的網(wǎng)絡請求分別添加到組中俯在,當組中所有隊列處理完事件后調(diào)用dispatch_group_notify搔确,我們需要在里邊處理事件彼棍。由于隊列在處理網(wǎng)絡請求時將”發(fā)送完一個請求”作為事件完成的標記(此時還未獲得網(wǎng)絡請求返回數(shù)據(jù)),所以在這里需要用信號量進行控制膳算,在執(zhí)行dispatch_group_notify前發(fā)起信號等待(三次信號等待座硕,分別對應每個隊列的信號通知),在每個隊列獲取到網(wǎng)絡請求返回數(shù)據(jù)時發(fā)出信號通知涕蜂。這樣就能完成需求中的要求华匾。
如果需求中改為:同時存在A,B,C三個任務,要求ABC依次進行處理机隙,當上一個完成時再進行下一個任務瘦真,當三個任務都完成時再處理事件。這時只需要將隊列改為串行隊列即可(不在需要信號量控制)黍瞧。
二诸尽、處理高并發(fā)請求完成后數(shù)據(jù)集合的一一對應關系
假如for遍歷發(fā)送HTTP并發(fā)請求時,由于服務端響應數(shù)據(jù)的時間不同印颤,會造成請求到的數(shù)據(jù)集合與發(fā)請求的順序非一一對應您机,思路如下,創(chuàng)建可變字典NSMutableDictionary
建立起請求與數(shù)據(jù)集合的對應關系。然后遍歷字典际看,按key
的順序重新整理數(shù)據(jù)集合
NSMutableDictionary *twoCategoryData = [NSMutableDictionary dictionary];
[_bigDict setObject:twoSmallDataArr forKey:[NSString stringWithFormat:@"%ld",index]];
if (_bigDict.count == _oneCategoryData.count) {
for (int i=0; i<_oneCategoryData.count; i++) {
NSArray *arr = [_bigDict objectForKey:[NSString stringWithFormat:@"%d",i]];
[_twoCategoryData addObject:arr];
}
項目中源碼參考
// 獲取一級分類data
- (void)getCategory {
[HTTPMANGER getFirstLevelCategoryListSuccessedBlock:^(NSDictionary *resultDict) {
NSLog(@"resultDict:%@",resultDict);
if (DATAINFO_SUCCESS) {
// 一級分類數(shù)組
_oneCategoryData = [NSMutableArray array];
_twoCategoryData = [NSMutableArray array];
_bigDict = [NSMutableDictionary dictionary];
for (NSDictionary *dic in DATA) {
CategoryModel *categoryModel = [CategoryModel initJson:dic];
[_oneCategoryData addObject:categoryModel];
// 創(chuàng)建信號量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 創(chuàng)建全局并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSUInteger index = [DATA indexOfObject:dic];
[self getTwoClassData:dic index:index];
dispatch_semaphore_signal(semaphore);
});
dispatch_group_notify(group, queue, ^{
// 請求對應信號等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
});
}
}
} failedBolck:^(NSError *error) {
NSLog(@"error:%@",error);
}];
}
// 獲取二級分類data
- (void)getTwoClassData:(NSDictionary *)dic index:(NSUInteger)index {
[HTTPMANGER getSecondLevelCategoryListWithCategoryId:dic[@"CATEGORY_ID"] successedBlock:^(NSDictionary *resultDict) {
NSLog(@"resultDict:%@",resultDict);
NSMutableArray *twoSmallDataArr = [NSMutableArray array];
NSMutableDictionary *twoCategoryData = [NSMutableDictionary dictionary];
for (NSDictionary *smalldic in DATA) {
CategoryModel *smallModel = [CategoryModel initJson:smalldic];
[twoCategoryData setObject:smallModel.CATEGORY_NAME forKey:@"name"];
[twoCategoryData setObject:smallModel.CATEGORY_ID forKey:@"type"];
[twoCategoryData setObject:smallModel.SUPER_CATEGORY_ID forKey:@"super"];
[twoSmallDataArr addObject:twoCategoryData];
}
//[_twoCategoryData addObject:twoSmallDataArr];
[_bigDict setObject:twoSmallDataArr forKey:[NSString stringWithFormat:@"%ld",index]];
if (_bigDict.count == _oneCategoryData.count) {
for (int i=0; i<_oneCategoryData.count; i++) {
NSArray *arr = [_bigDict objectForKey:[NSString stringWithFormat:@"%d",i]];
[_twoCategoryData addObject:arr];
}
[self initSearchBar];
}
} failedBolck:^(NSError *error) {
NSLog(@"error:%@",error);
}];
}