裹在具有完成塊爲參數的輔助方法的異步請求NSURLConnection的:
-(void) asyncDoSomething:(void(^)(id result)completionHandler ;
此方法應在NSURLConnectionDelegate
來實現。有關詳細信息,請參閱下面的示例實施和評論
其他地方,在您的操作方法中:
設置完成處理程序。該塊將在主線程上進一步分派,然後執行適當的任何更新表數據,除非結果是錯誤,在這種情況下,您應該顯示警報。
- (IBAction) recordButtonPressed
{
[someController asyncConnectionRequst:^(id result){
if (![result isKindOfClass:[NSError class]]) {
dispatch_async(dispatch_get_main_queue(), ^{
// We are on the main thread!
someController.tableData = result;
});
}
}];
}
方法的實現asyncConnectionRequst:
可以工作如下:取塊拿在伊娃。適當時用正確的參數調用它。但是,將塊作爲ivars或屬性會增加無意中引入循環引用的風險。
但是,還有一個更好的辦法:一個包裝塊將立即發送到暫停串行調度隊列 - 這是作爲一個伊娃。由於隊列被暫停,他們不會執行任何塊。只有等待隊列恢復後,該塊纔會執行。您恢復隊列在connectionDidFinish:
和connectionDidFailWithError:
(見下圖):
在你NSURLConnectionDelegate:
-(void) asyncConnectionRequst:(void(^)(id result)completionHandler
{
// Setup and start the connection:
self.connection = ...
if (!self.connection) {
NSError* error = [[NSError alloc] initWithDomain:@"Me"
code:-1234
userInfo:@{NSLocalizedDescriptionKey: @"Could not create NSURLConnection"}];
completionHandler(error);
});
return;
}
dispatch_suspend(self.handlerQueue); // a serial dispatch queue, now suspended
dispatch_async(self.handlerQueue, ^{
completionHandler(self.result);
});
[self.connection start];
}
然後在NSURLConnectionDelegate,派遣一個處理程序,並恢復 處理隊列:
- (void) connectionDidFinishLoading:(NSURLConnection*)connection {
self.result = self.responseData;
dispatch_resume(self.handlerQueue);
dispatch_release(_handlerQueue), _handlerQueue = NULL;
}
同樣,當發生錯誤時:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
self.result = error;
dispatch_resume(self.handlerQueue);
dispatch_release(_handlerQueue), _handlerQueue = NULL;
}
甚至有更好的方法,然而這涉及一些更基本的輔助類,其處理異步架構,其在一天結束的時候讓你的異步代碼看起來像它是同步的:
-(void) doFourTasksInAChainWith:(id)input
{
// This runs completely asynchronous!
self.promise = [self asyncWith:input]
.then(^(id result1){return [self auth:result1]);}, nil)
.then(^(id result2){return [self fetch:result2];}, nil)
.then(^(id result3){return [self parse:result3];}, nil)
.then(^(id result){ self.tableView.data = result; return nil;}, ^id(NSError* error){ ... })
// later eventually, self.promise.get should contain the final result
}
你的意思是你想一種同步的方式來進行上傳? – Wain
上傳已經完成。我只想要一種同步的方式在開始錄製之前從php腳本中獲取配置設置。 – user
永遠不要在UI線程中等待。 –