2012-06-15 16 views
12

tôi sử dụng phương pháp này để bắt đầu AFNetworking nhiều yêu cầu cùng một lúc:AFNetworking: enqueueBatchOfHTTPRequestOperations vấn đề với kết thúc khối

- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations 
           progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock 
          completionBlock:(void (^)(NSArray *operations))completionBlock 

Một trong số đó là một AFJSONRequestOperation. Vấn đề là khối thành công của hoạt động JSON này được thực hiện sau khi khối hoàn thành của lô. Lý do là: AFJSONRequestOperation có một hàng đợi công văn nội bộ để xử lý JSON. Vì vậy, dữ liệu JSON vẫn đang được xử lý trong khi khối hoàn thành được gọi.

Câu hỏi: Làm cách nào để thực thi mã trong khối hoàn thành sau khối thành công của thao tác JSON đã được gọi?

Tôi đã cố gắng gửi khối mã trên hàng đợi chính nhưng điều đó không có tác dụng.

Trả lời

1

Nếu có thể, giải pháp đơn giản nhất có thể là chỉ di chuyển mã xử lý của bạn từ khối thành công của từng hoạt động đến khối hoàn thành của toàn bộ lô.

Bạn có NSArray *operations sẵn trong khối hoàn thành, bạn có thể lặp qua các hoạt động và tìm kiếm:

for(AFHTTPRequestOperation *operation in operations){ 
    if(operation.response.statusCode == 200){ 
     //Do something with the response 
    }else{ 
    //Handle the failure 
    } 
} 

Bạn cũng có địa chỉ url cho mỗi hoạt động có sẵn thông qua operation.request.URL thuộc tính nếu bạn cần để phôi hành động khác nhau

+0

OP cho biết json vẫn chưa được xử lý khi hoàn thành được gọi, vì vậy điều này sẽ không hoạt động, phải không? – kevboh

+0

Vâng, đó là lý do tôi hỏi. Vì vậy, câu trả lời này không giúp tôi. – Felix

+1

Ồ đúng, tôi đã đọc sai. Đối với vấn đề của bạn, có thể có một bản vá sớm nếu bạn có thể chờ đợi. https://github.com/AFNetworking/AFNetworking/issues/362 –

0

Bạn có thể di chuyển thao tác Json của bạn đến đầu hàng đợi và sau đó thêm phụ thuộc để thao tác khác chỉ có thể bắt đầu sau khi thao tác json kết thúc:

[lastOperation addDependency:jsonOperation] 
+0

Bạn có thể cụ thể hơn không? –

+0

tôi đoán một cái gì đó như thế này: if (previousOperation) {[operation addDependency: previousOperation]; } previousOperation = operation; [operation addObject: hoạt động]; nó không hoạt động với tôi – Sosily

0

Có vẻ như không có cách nào dễ dàng để thực hiện chính xác những gì mà OP yêu cầu, vì vậy dưới đây là một số cách giải quyết dễ dàng.

Một chiến lược khá cùn là sử dụng AFHTTPRequestOperation thay vì AFJSONRequestOperation và sau đó chuyển đổi phản hồi bằng cách sử dụng NSJSONSerialization.

Vì vậy, các khối thành công của các hoạt động sẽ trông như thế

success:^(AFHTTPRequestOperation *operation, id responseObject){ 
       NSError *error ; 
       id json = [NSJSONSerialization JSONObjectWithData:responseObject 
              options:kNilOptions error:&error] ; 
       ... 
      } 

Hãy cẩn thận sẽ áp dụng - để được trả lời JSON lớn này có khả năng ngăn chặn mã, và một số các biện pháp khắc phục AFNetworking để NSJSONSerialization vấn đề này sẽ không áp dụng. Nhưng điều này sẽ giúp bạn đi.

Cập nhật: Người nhận xét đầu tiên bên dưới đề xuất sử dụng AFJSONRequestOperation và gọi responseJSON trên đó trong khối hoàn thành hàng loạt. Tôi tốt với điều đó nếu tình hình của bạn cho phép nó. Trong trường hợp sử dụng hiện tại của tôi nó phức tạp mã của tôi một chút (tôi đang sử dụng một tập hợp hỗn hợp các cuộc gọi JSON, do đó, mã là sạch hơn nếu tôi có thể giữ nó trong một khối success trực tiếp liên quan đến hoạt động).

+0

Sẽ có ý nghĩa hơn khi sử dụng thao tác JSON và chỉ cần gọi 'responseJSON' trên nó trong khối hoàn thành khối. Phương thức này trả về đồng bộ. Điều này cung cấp hành vi mà OP mong muốn mà không cần phải nhắc đến. –

+0

Cảm ơn @Aaron. Tôi đã cập nhật câu trả lời của mình. – brainjam