Heim > Fragen und Antworten > Hauptteil
利用AFNetworking进行网络请求,要发送的参数在一个数组里,每次取数组中的一条数据设置参数发送请求,
我通过for循环遍历数组并设置参数发送请求,将网络请求返回的数据添加到一个新的数组中,
发现不是每次请求返回的数据的顺序是一样的,功能需求返回数据的排序必须跟发送请求的顺序是一样的,
求问有什么方法保证前一次请求返回数据之后再发送下一次请求?
非常感谢,万分感谢!!!!
/**
* 加载订单数据,设置控件位置
*/
- (void)loadOrderData {
NSString *userID = [[NSUserDefaults standardUserDefaults] stringForKey:@"GOId"];
NSDictionary *dict = @{
@"GOId" : userID,
};
// 将字典转为json
NSDictionary *params = [ELHOCToJson ocToJson:dict];
NSString *URL = [NSString stringWithFormat:@"%@RealtimeOrder_getROListCon12345.action", ELHBaseURL];
__weak typeof(self) weakSelf = self;
[self.manager POST:URL parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
weakSelf.ELHOrderArray = [ELHOrderModel mj_objectArrayWithKeyValuesArray:responseObject];
dispatch_queue_t conCurrentQueue = dispatch_queue_create("order", NULL);
// 获取订单编号
for (int i = 0; i < weakSelf.ELHOrderArray.count; i++) {
ELHOrderModel *model = weakSelf.ELHOrderArray[i];
[weakSelf.ELHOrderNumArray addObject:model.ROBM];
dispatch_barrier_async(conCurrentQueue, ^{
// 加载订单详情列表
[self loadOrderDetailData:model.ROBM]; // 问题可能就出在这个for循环里,发送请求的顺序应该是按顺序发送的,但是返回数据的时间可能就不一样了,所以造成了数据顺序错乱的问题,求问如何解决此问题?
});
}
// 刷新数据
[orderVC.tableView reloadData];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@", error);
}];
}
/**
* 加载订单详情列表
*/
- (void)loadOrderDetailData:(NSString *)ROBM {
NSDictionary *dict = @{
@"ROBM" : ROBM,
};
// 字典转json
NSDictionary *params = [ELHOCToJson ocToJson:dict];
NSString *URL = [NSString stringWithFormat:@"%@OrderPrice_getOPListByROBM.action", ELHBaseURL];
__weak typeof(self) weakSelf = self;
[self.manager POST:URL parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// 将获取到的订单详情数据逐个添加到数组中
[weakSelf.ELHOrderDetailArray addObject:[ELHOrderDetailModel mj_objectArrayWithKeyValuesArray:responseObject]];
ELHOrderTableViewController *orderVC = weakSelf.childViewControllers.firstObject;
orderVC.orderDetailArray = weakSelf.ELHOrderDetailArray;
// 刷新数据
[orderVC.tableView reloadData];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@", error);
}];
}
阿神2017-04-17 17:53:19
我找到了一中折中的办法,就是在afnetworking的回调里用dispatch_group_async
函数进行顺序控制
代码如下:
[self.manager POST:URL parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// NSLog(@"%@", responseObject);
// 字典数组转模型数组
weakSelf.ELHOrderArray = [ELHOrderModel mj_objectArrayWithKeyValuesArray:responseObject];
// 获取订单编号
for (int i = 0; i < weakSelf.ELHOrderArray.count; i++) {
ELHOrderModel *model = weakSelf.ELHOrderArray[i];
// 将订单编号存入一个数组,亦可以不存直接进行获取订单列表操作,加这一步因为项目需求
[weakSelf.ELHOrderNumArray addObject:model.ROBM];
}
/**
* 根据上面获取到的订单编号数组,遍历数组 获取 订单列表
*/
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:weakSelf.ELHOrderNumArray]; // 创建临时数组用于存放接收到的数据,确保临时数组的长度和你请求到的数据的组数是一样的,这样才能保证你"第几个请求返回的数据放在数组的第几个位置", 这句代码 [tempArray setObject:responseDict atIndexedSubscript:i]; 实现该功能
if (weakSelf.ELHOrderNumArray != nil) {
dispatch_queue_t queue = dispatch_queue_create("order", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
for (int i = 0; i < weakSelf.ELHOrderNumArray.count ; i++) {
dispatch_group_async(group, queue, ^{
NSString *urlStr = [NSString stringWithFormat:@"%@OrderPrice_getOPListByROBM.action", ELHBaseURL];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [[NSString stringWithFormat:@"jo={ROBM=%@}", weakSelf.ELHOrderNumArray[i]] dataUsingEncoding:NSUTF8StringEncoding];
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
// 第几个请求返回的数据放在数组的第几个位置
[tempArray setObject:responseDict atIndexedSubscript:i];
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 将所有请求到的数据按顺序放到一个数组中,之后进行别的操作刷新数据就可以了
[self.ELHOrderDetailArray addObjectsFromArray:[ELHOrderDetailModel mj_objectArrayWithKeyValuesArray:tempArray]];
......
[self.tableView reloadData];
});
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@", error);
}];
PHP中文网2017-04-17 17:53:19
看了下文档 operationQueue
是用来处理 delegate
回调的, NSURLSessionConfiguration
的 HTTPMaximumConnectionsPerHost
可以保证同一域名下每次只发起一个请求, 代码如下:
NSURLSessionConfiguration *configure = [NSURLSessionConfiguration defaultSessionConfiguration];
configure.HTTPMaximumConnectionsPerHost = 1;
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configure];
manager.operationQueue.maxConcurrentOperationCount = 1;
不过 AFNetworking
使用了并行队列 url_session_manager_processing_queue()
处理数据, 由于不能保证这个队列的先后性, 所以其实也不能够确保回调的串行性
----------------------------------------原答案-----------------------------
把 manger
里 queue
的 maxConcurrentOperationCount
设置成 1.
还有你这里的 dispatch_barrier_async
我不知道你是想干嘛, 保证串行? 你这个 for
循环本来就是串行的啊