Оберните асинхронный запрос 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:
может работу следующим образом: возьмите блок и держать его в Ивар. Когда это целесообразно, назовите его правильным параметром. Однако наличие блоков как иваров или свойств увеличит риск непреднамеренного введения круговых ссылок.
Но есть лучший способ: блок-оболочка будет немедленно отправлен в приостановленный последовательной очереди отправки - который удерживается как ivar. Поскольку очередь приостановлена, они не будут выполнять никаких блоков. Только до тех пор, пока очередь не будет возобновлена, блок будет выполняться. Возобновление очереди в вашем 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
Никогда не ждите в потоке пользовательского интерфейса. –