2013-04-17 28 views
6

我想在一個特定的函數中實現異步的url請求,我想要完成所有這些請求,然後執行一個特定的動作,但動作先於請求,即在請求完成之前調用它。dispatch_async裏面的異步url請求

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

現在在myAsyncMultipleURLRequestFunction完成所有請求之前調用updateUIFunction。也試過這與NSOperaitonQueue,但不能做我真正想要的。

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

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

我知道這很簡單,但我運行失控時間,任何幫助表示讚賞。

回答

10

@tkanzakic是在正確的道路上。使用正確的構造是dispatch_group_t。但是實施可以改進。通過使用信號量,您可以異步啓動所有下載,並確保您沒有太多的併發運行。這裏是一個代碼示例,說明你應該如何使用dispatch_group_t以及使所有下載並行:

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

我會試試這個,看起來很有前途。 – satheeshwaran

+0

它適合你嗎? – aLevelOfIndirection

3

您可以創建一個dispatch_group_t然後用dispatch_group_notify執行updateUIFunction當組完成運行後的前一個塊,例如:

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

謝謝你會試試這個,讓你知道! – satheeshwaran

+0

嘿@tkanzakic它不工作,和以前一樣。在myAsyncMultipleURLRequestFunction完成之前,updateUIFUnction被調用。 – satheeshwaran

+0

我對'dispatch_group_notify'塊進行了一些修改,我記得我需要這樣實現它,這是一個項目,順便嘗試一下 – tkanzakic

1

首先配置運行循環。

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

試試這個

+0

你是什麼意思self.finished在這裏?它是一個BOOL? – satheeshwaran