2013-05-16 45 views
2

我目前在我的iPhone應用程序之一使用AFNetworking。這是一個非常方便的庫來進行異步調用。但是,我在我的應用程序中遇到了需要從服務器獲取數據的情況。所以我想通過這種等待回覆的方式。同步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 .:同步做請求並不意味着阻止man線程。您在開始同步請求時可能已處於後臺。出於某種原因,當有人要求同步網絡請求時,整個iOS社區unisono會響應「不要」。 –

+1

@KaiHuppmann你完全錯了。如果你不相信社區的一致意見,至少應該聽取蘋果的意見:[(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

對於所有的人誰是運行在同一個情況下,你正在異步調用,並希望等待數據要返回到主線程做其他的東西,這可能是有點幫助

場景:

用戶認證:用戶輸入用戶名,密碼,並試圖登錄

解決方案:顯示它們加載模式告訴他們的東西是怎麼回事幕後,一旦ÿ你可以回到主線程,如下圖所示。

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

} 

感謝@matt的提示,在這種情況下需要做些什麼。

+1

等待一段固定的時間在這裏不是一個可行的選擇 - 它可能與做同步網絡一樣糟糕。 您應該始終使用AFNetworking提供的相應回調模塊。 要正確使用它們,您需要構建應用程序的其餘部分,以便它對異步友好。授權是一個好主意,然後使用。 –

+0

@MatthiasWenz是正確的 - 這不是一個可接受的解決方案。 – mattt