0

Мне нужно отправить 100 сетевых запросов на мой сервер один за другим и получить уведомление, когда выполнено 100-е.Отправить несколько запросов по одному

Я использую AFNetworking и думал о решении этой проблемы. Может ли кто-нибудь мне что-нибудь рекомендовать?

ответ

0

Это конкретная форма общего вопроса, которая называется «как я могу назвать последовательность операций с блоками и получать уведомление, когда последний заканчивается?»

Одна из идей - создать «список дел» с использованием параметров для каждого запроса. Скажем, каждый запрос занимает число 0..99. Теперь псевдо-код будет выглядеть следующим образом:

@property(nonatomic, copy) void (^done)(BOOL);  // we'll need to save a completion block 
@property(nonatomic, strong) NSMutableArray *todo; // might as well save this too 

- (void)makeRequestsThenInvoke:(void (^)(BOOL))done { 

    self.todo = [NSMutableArray arrayWithArray:@[@99, @98, @97 ... @0]]; 
    // make this in a loop using real params to your network request (whatever distinguishes each request) 

    self.done = done; 
    [self makeRequests]; 
} 


- (void)makeRequests { 

    if (!self.todo.count) { // nothing todo? then we're done 
     self.done(YES); 
     self.done = nil;  // avoid caller-side retain cycle 
     return; 
    } 
    // otherwise, get the next item todo 
    NSNumber *param = [self.todo lastObject]; 
    // build a url with param, e.g. http://myservice.com/request?param=%@ <- param goes there 

    [afManager post:url success:success:^(AFHTTPRequestOperation *operation, id responseObject) { 

     // handle the result 

     // now update the todo list 
     [self.todo removeLastObject]; 
     // call ourself to do more, but use performSelector so we don't wind up the stack 
     [self performSelector:@selector(makeRequests) withObject:nil afterDelay:0.0]; 
    }]; 
} 
+0

Незначительная проблема - ваш селектор называется 'makeRequests', но вы вызываете' makeRequests: '. –

+0

Ах. Благодарю. Будет редактировать. – danh

3

Пара мыслей:

  1. Если действительно только собирается запустить каждый запрос последовательно (т.е. один за другим), то вы можете сделать:

    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    queue.maxConcurrentOperationCount = 1; 
    
    NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{ 
        NSLog(@"All operations done"); 
    }]; 
    
    for (NSInteger i = 0; i < operationCount; i++) { 
        AFHTTPRequestOperation *operation = ... // create your operation here 
    
        [completionOperation addDependency:operation]; 
    
        [queue addOperation:operation]; 
    } 
    
    [queue addOperation:completionOperation]; 
    

    Примечание. Использование очереди операций, как это дает преимущество, что вы можете легко отменить все операции в этой очереди, если вам когда-либо понадобится.

    Если порядок, что они выполняются очень важно, вы можете установить явные зависимости между операциями, например:

    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    queue.maxConcurrentOperationCount = 1; 
    
    NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{ 
        NSLog(@"All operations done"); 
    }]; 
    
    NSOperation *priorOperation = nil; 
    
    for (NSInteger i = 0; i < operationCount; i++) { 
        AFHTTPRequestOperation *operation = ... // create your operation here 
    
        [completionOperation addDependency:operation]; 
    
        if (priorOperation) [operation addDependency:priorOperation]; 
    
        [queue addOperation:operation]; 
    
        priorOperation = operation; 
    } 
    
    [queue addOperation:completionOperation]; 
    
  2. вопрос для меня абсолютно ли вы только хотите, чтобы запустить один за другим время. Вы платите за это значительное снижение производительности. Как правило, вы должны использовать этот первый пример кода (где только явные зависимости относятся к операции завершения) и установить maxConcurrentOperationCount на что-то вроде 4, наслаждаясь параллелизмом и соответствующим следствием производительности (в то же время, ограничивая степень параллелизма какое-то разумное число, которое не будет использовать все ваши рабочие потоки, рискует получить тайм-аут запросов и т. д.).

  3. Вы не сказали, что такое 100 операций, но если это куча загрузок, вам может потребоваться шаблон «ленивой загрузки», который будет загружать данные асинхронно, ,

    Если вы загружаете изображения, например, вы можете достичь этого, используя категорию AFNetworking UIImageView.

Смежные вопросы