一、处理高并发请求的核心代码如下:
// 创建信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 创建全局并行
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);
});
分析:
首先创建并行队列,创建队列组,将队列和需要处理的网络请求分别添加到组中,当组中所有队列处理完事件后调用dispatch_group_notify,我们需要在里边处理事件。由于队列在处理网络请求时将”发送完一个请求”作为事件完成的标记(此时还未获得网络请求返回数据),所以在这里需要用信号量进行控制,在执行dispatch_group_notify前发起信号等待(三次信号等待,分别对应每个队列的信号通知),在每个队列获取到网络请求返回数据时发出信号通知。这样就能完成需求中的要求。
如果需求中改为:同时存在A,B,C三个任务,要求ABC依次进行处理,当上一个完成时再进行下一个任务,当三个任务都完成时再处理事件。这时只需要将队列改为串行队列即可(不在需要信号量控制)。
二、处理高并发请求完成后数据集合的一一对应关系
假如for遍历发送HTTP并发请求时,由于服务端响应数据的时间不同,会造成请求到的数据集合与发请求的顺序非一一对应,思路如下,创建可变字典NSMutableDictionary
建立起请求与数据集合的对应关系。然后遍历字典,按key
的顺序重新整理数据集合
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) {
// 一级分类数组
_oneCategoryData = [NSMutableArray array];
_twoCategoryData = [NSMutableArray array];
_bigDict = [NSMutableDictionary dictionary];
for (NSDictionary *dic in DATA) {
CategoryModel *categoryModel = [CategoryModel initJson:dic];
[_oneCategoryData addObject:categoryModel];
// 创建信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
// 创建全局并行
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);
}];
}
网友评论