AFNetworking: enqueueBatchOfHTTPRequestOperations проблема с блоком завершения
Я использую этот метод AFNetworking для запуска сразу нескольких запросов:
- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations
progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock
completionBlock:(void (^)(NSArray *operations))completionBlock
Один из них - AFJSONRequestOperation
. Проблема в том, что блок успеха этой операции JSON выполняется после блока завершения пакета. Причина такова: AFJSONRequestOperation
имеет внутреннюю очередь отправки для обработки JSON. Таким образом, данные JSON все еще обрабатываются, пока вызывается блок завершения.
Вопрос: Как выполнить код в блоке завершения после был вызван успешный блок операции JSON?
Я попытался отправить блок кода в основную очередь, но это не помогло.
Ответы
Ответ 1
Если это возможно, самым простым решением может быть просто переместить код обработки из блока успешности каждой операции в блок завершения всей партии.
У вас есть NSArray *operations
, доступный в блоке завершения, вы можете выполнять итерацию по этим операциям и искать:
for(AFHTTPRequestOperation *operation in operations){
if(operation.response.statusCode == 200){
//Do something with the response
}else{
//Handle the failure
}
}
У вас также есть адрес URL-адреса для каждой операции, доступной через свойство operation.request.URL
, если вам нужно предварительно выполнить различные действия.
Ответ 2
Вы можете перенести операцию Json в начало очереди, а затем добавить зависимость, чтобы другая операция начиналась только после завершения операции json:
[lastOperation addDependency:jsonOperation]
Ответ 3
Похоже, что нет простого способа сделать то, что запросит OP, так что вот несколько простых обходных решений.
Скорее тупой стратегией было бы использовать AFHTTPRequestOperation
вместо AFJSONRequestOperation
, а затем преобразовать ответ с помощью NSJSONSerialization
.
Таким образом, блок успеха операции будет выглядеть как
success:^(AFHTTPRequestOperation *operation, id responseObject){
NSError *error ;
id json = [NSJSONSerialization JSONObjectWithData:responseObject
options:kNilOptions error:&error] ;
...
}
Предостережения будут применяться - для больших ответов JSON это потенциально блокирует код, а некоторые из обходных решений AFNetworking для NSJSONSerialization
не будут применяться. Но это заставит вас идти.
Обновление:. В первом комментарии ниже предлагается использовать AFJSONRequestOperation
и вызывать responseJSON
на нем в блоке завершения партии. Я согласен с этим, если это позволяет ваша ситуация. В моем текущем случае использования это немного усложняет мой код (я использую смешанный набор вызовов JSON, поэтому код чище, если я могу сохранить его в блоке success
, непосредственно связанном с операцией).