2013-05-16 2 views
2

В настоящее время я использую AFNetworking в одном из моих iPhone-приложений. Это действительно удобная библиотека для асинхронных вызовов. Однако я столкнулся с ситуациями в своем приложении, где мне нужно получить данные с сервера, чтобы двигаться вперед. Поэтому я решил, что так жду ответа.Синхронные вызовы AFNetworking

MyAFNetworkClient *httpClient = [MyAFNetworkClient sharedClient]; 

    NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:path parameters:nil]; 

__block int status = 0; 

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"notificationName" object:JSON]; 

} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){ 
    @throw error.userInfo; 
    status = 2; 
    NSLog(@"Error... Status Code 2"); 

}]; 
[httpClient enqueueHTTPRequestOperation:operation]; 
[httpClient.operationQueue waitUntilAllOperationsAreFinished]; 

while (status == 0) 
{ 
    // run runloop so that async dispatch can be handled on main thread AFTER the operation has 
    // been marked as finished (even though the call backs haven't finished yet). 
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
          beforeDate:[NSDate date]]; 
} 

С помощью этой части кода я могу дождаться ответа с сервера и продолжить движение дальше. Это действительно помогло решить мою проблему, однако, не уверен, что это хороший способ совершать звонки. Если это так, есть хороший принцип дизайна, где я могу сохранить общий код и использовать его в моем приложении.

Спасибо

+0

Я думаю, что ответы/комментарии здесь иллюстрируют основанный на мнениях характер этого вопроса. –

ответ

12

Никогда не блокируйте основную (UI) резьбу. То есть никогда не делайте сетевой синхронно.

За все время, когда ваш запрос загружается, вы увидите, что ваше приложение заморожено - полностью не реагирует на касание и системные события, пока запрос не завершится.

По крайней мере, покажите загружаемый способ, который не будет отклонен, пока запрос не завершится. Еще лучше, сделайте так, чтобы пользователь мог нормально взаимодействовать с приложением при загрузке, если это возможно.

То, что у вас здесь, может технически работать, но оно неприемлемо для реального применения.

+9

@matt не так! 1: могут быть причины блокировки основной нити. Я не думаю, что вы можете это исключить для каждого приложения в любой ситуации. 2 .: Выполнение запросов синхронно не означает блокировку потока пользователя. Вы можете быть в фоновом режиме уже при запуске синхронного запроса. По какой-то причине все сообщество iOS-сообщества unisono отвечает «НЕ», когда кто-то запрашивает синхронный сетевой запрос. –

+1

@KaiHuppmann Вы полностью ошибаетесь. И если вы не доверяете единодушному мнению сообщества, по крайней мере, возьмите Apple по их слову: [(1)] (https://developer.apple.com/library/ios/qa/qa1693/_index.html) [(2)] (https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html) – mattt

+0

Как насчет того, когда вам нужно загрузить список свойств, то есть необходимо для запуска приложения? его можно использовать, особенно сразу после нажатия кнопки «Войти в систему». У меня есть данные настроек клиента на удаленном сервере, и все это должно уважать эти настройки. Когда pList еще не загружен, приложение не может предложить пользователю правильное использование. – pedrouan

0

Для всех из них, кто работает в той же ситуации, когда вы делаете асинхронные вызовы и хотите ждать, пока данные, чтобы вернуться обратно в основной поток, чтобы делать другие вещи, это может быть небольшой помощью

Сценарий:

аутентификация пользователя: Пользователь вводит имя пользователя, пароль и пытается войти в

Решение:. Покажите их загрузки модального, чтобы сказать им, что это то, что происходит за кулисами, когда у ou верните ответ, вы можете перейти к основному потоку, как показано ниже.

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
     // perform next steps.... 
     }); 

} 

Спасибо @matt за отзыв о том, что необходимо сделать в таких случаях.

+1

Ожидание фиксированного количества времени здесь не является жизнеспособным вариантом - это, вероятно, так же плохо, как и синхронная сеть. Вы всегда должны использовать соответствующие блоки обратного вызова, которые предоставляет AFNetworking. Чтобы использовать их правильно, вам необходимо архивировать остальную часть вашего приложения, чтобы он был асинхронным. Делегирование - хорошая идея для использования. –

+0

@ MatthiasWenz является правильным - это не приемлемое решение. – mattt

Смежные вопросы