2013-04-17 14 views
6

Sto cercando di implementare richieste di url asincrone in una particolare funzione, voglio che tutte queste richieste vengano completate e poi eseguo un'azione particolare ma l'azione precede le richieste cioè, viene chiamata prima che le richieste siano complete .richieste di url asincroni all'interno di dispatch_async

dispatch_queue_t fetchQ = dispatch_queue_create("Featured Doc Downloader", NULL); 
     dispatch_async(fetchQ, ^{ 
      [self myAsyncMultipleURLRequestFunction]; 
      dispatch_sync(dispatch_get_main_queue(), ^{ 
       [self updateUIFunction]; 
      }); 
     }); 

-(void)myAsyncMultipleURLRequestFunction 
    { 
    for (int i=0; i<count; i++) 
    { 
    NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];   
    } 
    } 

ora updateUIFunction viene chiamato prima myAsyncMultipleURLRequestFunction completa tutte le richieste. Ho provato anche questo con NSOperaitonQueue, ma non ho potuto fare ciò che volevo veramente.

[_operationQ addOperationWithBlock:^{ 
    for (int i=0; i<count; i++) 
     { 
    NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];   
     } 
    } 

[[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     // updating UI 
     [self updateUIFunction]; 
    }]; 
}]; 

So che questo è semplice ma sto scappando dal tempo, ogni aiuto è apprezzato.

risposta

10

@tkanzakic è sulla strada giusta. Il costrutto corretto da usare è il dispatch_group_t. Ma l'implementazione potrebbe essere migliorata. Utilizzando un semaforo è possibile avviare tutti i download in modo asincrono e accertarsi comunque di non averne troppi in esecuzione contemporaneamente. Ecco un esempio di codice che illustra come si dovrebbe usare dispatch_group_t e tutti i tuoi download paralleli:

dispatch_queue_t fetchQ = dispatch_queue_create("Featured Doc Downloader", NULL); 
dispatch_group_t fetchGroup = dispatch_group_create(); 

// This will allow up to 8 parallel downloads. 
dispatch_semaphore_t downloadSema = dispatch_semaphore_create(8); 

// We start ALL our downloads in parallel throttled by the above semaphore. 
for (int i=0; i<count; i++) { 
    dispatch_group_async(fetchGroup, fetchQ, ^(void) { 
     dispatch_semaphore_wait(downloadSema, DISPATCH_TIME_FOREVER); 
     NSURLConnection *loginConnection = [[NSURLConnection alloc] initWithRequest:requestArray[i] delegate:self]; 
     dispatch_semaphore_signal(downloadSema); 
    }); 
} 

// Now we wait until ALL our dispatch_group_async are finished. 
dispatch_group_wait(fetchGroup, DISPATCH_TIME_FOREVER); 

// Update your UI 
dispatch_sync(dispatch_get_main_queue(), ^{ 
    [self updateUIFunction]; 
}); 

// Release resources 
dispatch_release(fetchGroup); 
dispatch_release(downloadSema); 
dispatch_release(fetchQ); 
+0

Ci proverò, sembra promettente. – satheeshwaran

+0

Funziona per voi? – aLevelOfIndirection

3

è possibile creare un dispatch_group_t e quindi utilizzare dispatch_group_notify per eseguire il updateUIFunction quando il blocco precedente del gruppo terminata l'esecuzione, ad esempio:

dispatch_queue_t fetchQ = dispatch_queue_create("Featured Doc Downloader", NULL); 
dispatch_async(fetchQ, ^{ 
    dispatch_group_t group = dispatch_group_create(); 
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ 
     [self myAsyncMultipleURLRequestFunction]; 
    }); 
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self updateUIFunction]; 
     }); 
    }); 
}); 
+0

Grazie proveremo questo e ti faccio sapere! – satheeshwaran

+0

Ehi @tkanzakic non funziona, come prima. updateUIFUnction viene chiamato prima che myAsyncMultipleURLRequestFunction venga completato. – satheeshwaran

+0

Ho apportato una piccola modifica al blocco 'dispatch_group_notify', ricordo che ho bisogno di implementarlo in questo modo è un progetto, provatelo – tkanzakic

1

prima configurare ciclo eseguito.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; 
    [NSURLConnection connectionWithRequest:request delegate:self]; 
    while(!self.finished) { 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
    } 
}); 

Prova questa

+0

cosa intendi per self.finished qui ?? E 'un BOOL ?? – satheeshwaran

Problemi correlati