2013-04-17 29 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