2016-04-24 13 views
5

Tôi cần đợi một số yêu cầu AFNetworking hoàn thành, tôi đã thử sử dụng các nhóm công văn, nhưng dường như tôi không thể làm đúng.Đợi nhiều yêu cầu AFNetworking để hoàn thành

Dưới đây là mã của tôi:

dispatch_group_t group = dispatch_group_create(); 

for (int k = 0; k < 10 ; k++) { 
    dispatch_group_enter(group); 

    [[AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     dispatch_group_leave(group); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     dispatch_group_leave(group); 
    }]; 
} 

dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"DONE"); 

Vấn đề là nó bị mắc kẹt trên dispatch_group_wait, bởi vì không phải khối thành công, cũng không phải là khối thất bại này được gọi là.

Tôi có thể giải quyết nó bằng cách nào?

+0

Bạn đã thử sử dụng dispatch_group_notify chưa? – jtbandes

+0

có, hoạt động. Tuy nhiên điều đó không giải quyết được vấn đề của tôi. Do ứng dụng đã được xây dựng như thế nào (tôi đã kế thừa dự án), tôi cần phải ngừng thực hiện phương thức. – guidev

+0

Thật không may; bạn có thể muốn xem xét tái cấu trúc nó. Nếu bạn chặn các chủ đề, bạn sẽ lãng phí một chủ đề mà chỉ có công việc là để chờ đợi cho thread khác để làm một cái gì đó. libdispatch áp đặt một giới hạn 64 luồng mà nó sẽ khởi động để phục vụ hàng đợi, do đó, tùy thuộc vào ứng dụng của bạn đang làm gì, nó có thể trở thành một vấn đề. – jtbandes

Trả lời

6

Hàng đợi công văn cho completionBlock. Nếu NULL (mặc định), hàng đợi chính được sử dụng.

dispatch_group_t group = dispatch_group_create(); 

dispatch_queue_t queue = dispatch_queue_create("com.app", DISPATCH_QUEUE_CONCURRENT); 

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 
manager.completionQueue = queue; 
for(int k = 0; k < 10; k++) { 
    dispatch_group_enter(group); 

    dispatch_async(queue, ^{ 
     NSLog(@"%d", k); 
     [manager GET:@"http://baidu.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { 
      NSLog(@"success"); 
      dispatch_group_leave(group); 
     } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) { 
      NSLog(@"failure"); 
      dispatch_group_leave(group); 
     }]; 
    }); 
} 

dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 

NSLog(@"DONE"); 
0

Hãy thử điều này,

dispatch_group_t group = dispatch_group_create(); 

for (int k = 0; k < 10 ; k++) { 
    dispatch_group_enter(group); 

    [[AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     dispatch_group_leave(group); 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     dispatch_group_leave(group); 
    }]; 
} 

dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 

    NSLog(@"All done"); 

}); 

dispatch_group_notify sẽ được gọi khi tất cả các nhiệm vụ sẽ được hoàn thành.

0

Bạn có thể sử dụng PromiseKit. Rất mạnh mẽ.

tuần tự

 [self.manager GET:@"http://www.error-url.ss/" parameters:nil].then(^(id responseObject, AFHTTPRequestOperation *operation){ 
     NSLog(@"first request completed for operation: %@", operation.request.description); 
     return [self.manager GET:@"http://www.apple.com" parameters:nil]; 
    }).then(^{ 
     NSLog(@"second request completed"); 
    }).catch(^(NSError *error){ 
     NSLog(@"error happened: %@", error.localizedDescription); 
     NSLog(@"original operation: %@", error.userInfo[AFHTTPRequestOperationErrorKey]); 
    }); 

HOẶC (theo yêu cầu của bạn)

 [PMKPromise when:@[ 
         [self.operationManager GET:@"ip" parameters:nil].then(^(){numberOfOperationsCompleted ++;}), 
         [self.operationManager GET:@"get" parameters:nil].then(^(){numberOfOperationsCompleted ++;}) 
         ]].then(^(){ 
     //do something when all operations are finished 
    }); 
0

Bạn có thể sử dụng chức năng trợ giúp này để chặn chuỗi chính.

static inline void hxRunInMainLoop(void(^block)(BOOL *done)) { 
__block BOOL done = NO; 
block(&done); 
while (!done) { 
    [[NSRunLoop mainRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow:.1]]; 
} 
} 

Bạn cũng cần phải thực hiện bộ đếm và tăng nó thành công hay thất bại.

- (void)test { 
    __block int count = 0; 

    hxRunInMainLoop(^(BOOL *done) { 

    for (int i = 0; i < 10; i++) { 

    [AFHTTPSessionManager manager] GET:@"http://google.com/" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { 
     NSLog(@"success"); 
     count++; 
     if (count == 9) { 
     *done = YES; 
     } 
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { 
     NSLog(@"failure"); 
     count++; 
     if (count == 9) { 
     *done = YES; 
     } 
    }]; 
} 

Điều này sẽ chặn chuỗi chính cho đến khi hoàn tất được đặt thành CÓ.

Các vấn đề liên quan