6

Ich versuche asynchrone URL-Anfragen in einer bestimmten Funktion zu implementieren, ich möchte, dass alle diese Anfragen abgeschlossen sind und dann eine bestimmte Aktion ausführen, aber die Aktion wird den Anfragen vorangestellt, dh sie wird aufgerufen, bevor die Anfragen abgeschlossen sind .Asynchrone URL-Anfragen innerhalb von 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];   
    } 
    } 

Jetzt wird updateUIFunction aufgerufen, bevor myAsyncMultipleURLRequestFunction alle Anfragen abschließt. Habe das auch mit NSOperaitonQueue versucht aber konnte nicht das machen was ich wirklich will.

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

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

Ich weiß, das ist einfach, aber ich bin outta Zeit, jede Hilfe wird geschätzt.

Antwort

10

@tkanzakic auf dem richtigen Weg ist. Das richtige zu verwendende Konstrukt ist die dispatch_group_t. Aber die Implementierung könnte verbessert werden. Mit einem Semaphor können Sie alle Ihre Downloads asynchron starten und trotzdem sicherstellen, dass nicht zu viele gleichzeitig laufen. Hier ist ein Codebeispiel, das veranschaulicht, wie Sie dispatch_group_t verwenden und alle Ihre Downloads parallel machen sollten:

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

Ich werde das versuchen, sieht vielversprechend aus. – satheeshwaran

+0

Funktioniert es für Sie? – aLevelOfIndirection

3

Sie können eine dispatch_group_t erstellen und dann dispatch_group_notify verwenden, um die updateUIFunction, wenn der vorherige Block der Gruppe Finish Laufen, zum Beispiel auszuführen:

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

Vielen Dank, versuchen Sie dies und lassen Sie es wissen! – satheeshwaran

+0

Hey @tkanzakic es funktioniert nicht, dasselbe wie vorher. updateUIFUnction wird aufgerufen, bevor myAsyncMultipleURLRequestFunction abgeschlossen wird. – satheeshwaran

+0

Ich habe eine kleine Änderung des 'dispatch_group_notify' Blocks gemacht, ich erinnere mich, dass ich es auf diese Weise implementieren muss, ist ein Projekt, versuchen Sie es – tkanzakic

1

Erste Configure laufen Schleife.

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]]; 
    } 
}); 

Versuchen Sie, diese

+0

was meinst du mit self.finished hier ?? Ist es ein BOOL? – satheeshwaran

Verwandte Themen