2013-12-09 22 views
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類實現這一目標。