2011-04-18 85 views
9

我有一個基於導航的應用程序。按主視圖上的按鈕,然後將新視圖推送到導航控制器。所有非常基本的東西。asihttprequest崩潰我的應用程序

加載新視圖時,我執行一個ASIHTTPRequest來獲取一些json數據,這是一個圖像url的列表。 然後我做一個for循環,創建一堆ASIHTTPRequests,將它們添加到隊列中,然後運行隊列。

但是,如果在隊列結束之前點擊後退按鈕,應用程序崩潰,此應用程序會顯示房屋,並可以說您選擇了錯誤的房屋,在顯示任何照片之前快速點擊,併發生撞擊。

此線程http://groups.google.com/group/asihttprequest/browse_thread/thread/3d4815198aa889b9解釋我的問題真的很好,除非我取消所有視圖請求卸載,將委託設置爲零並釋放隊列。

我仍然崩潰。如果我使用3G,每次都會崩潰,但在WiFi上真的很難讓它崩潰,但相當可行。

在幾乎80%的情況下,調試器跳轉到該行ASIHTTPRequest.m

(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { 
    if ([self error] || [self mainRequest]) { return; } 
--> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) { 

許多許多情況下,跳轉到:

(void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { 
    if ([self error] || [self mainRequest]) { return; }  
---> if (delegate && [delegate respondsToSelector:didReceiveResponseHeadersSelector]) { 

廣告的情況下,極少數是去我主循環

int main(int argc, char *argv[]) { 
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
--> int retVal = UIApplicationMain(argc, argv, nil, nil); with SIGBART error [pool release]; return retVal; 

我使用MBP和MacPro,最新的OS X,Xcode 4.0.2和我測試所有除原裝iPhone之外的其他設備。

我真的不想重寫我的整個應用程序,但是還有什麼與ASIHTTPRequest相比?

回答

3

錯誤是委託仍然設置。

我發現有2種方法可以解決這個問題。

我認爲醜陋的一種方式是,您創建一個通用委託,執行所有網絡通信並在應用第一次運行時實例化。我實際上使用了應用程序委託並收聽nsnotification中心消息。它的作用就像一個魅力,應用程序從不崩潰,但我認爲這不是最佳。

最好的方法是不設置委託,不使用「setDidFinishSelector」,而是使用「setCompletionBlock:^」。這隻適用於運行iOS 4.0及更高版本的設備,這個數量超過了90-95%,並且在不斷增長。這只是一種非常棒的方式,不會使應用程序崩潰。

+0

很好的回答,它的工作 – KsK 2013-08-26 07:27:31

+0

使用第二種方法實際上有效。謝謝。我被困在這個上太久了。乾杯。 – 2014-02-11 09:23:51

3

你不會找到任何更好的ASIHTTPRequest,問題將是你如何使用它,消除導航代表是一個常見的問題,必須處理。

這聽起來像你的問題涉及到處理由於用戶導航而被銷燬的隊列的視圖控制器。我發現解決這些問題的最好方法是擁有一箇中央模型類,它處理我所有的通信並在整個應用生命週期中保持這個類。

這樣,當代表意外消失時,您不會得到無法解釋的崩潰。

選項2

另一種方法可以是,直到網絡操作完成來禁用用戶導航。在顯示uiactivityview的整個屏幕上放置一個模式視圖,以便用戶知道他們的操作被阻止。然後,您可以在數據到達時淡出模態視圖。如果你用漸變很好地設計屏幕,使背景變暗一點,這可以看起來不錯。但它不是最好的方法 - 你應該修復委託AWOL。

我們可能需要查看更多有關隊列創建,銷燬等的代碼才能找到確切的問題。

+0

這樣的中心階層會是什麼樣子? – 2011-04-18 18:20:54

+0

我想中心階層將是一個單身人士。 – 2011-08-12 16:07:09

+0

可以是單例或僅由實例化一次並由應用程序委託保留的類。 – Roger 2011-08-12 17:23:30

1

您的應用程序委託可以擁有一個請求隊列數組。數組獨立於導航控制器堆棧和相關視圖的狀態。您可以將請求添加到應用程序委託隊列實例,或停止所有請求並清空隊列等,而不必將請求綁定到導航堆棧中的視圖控制器,並且必須執行UI技巧來阻止彈出回到父視圖。

+0

你能解釋我將如何去做這樣一個單例委託,或者我會只使用App委託?你的想法聽起來很有趣,但我無法完全想象它。 – 2011-04-18 18:20:21

+0

只需使用應用程序代理。或者你可以創建一個由應用程序委託擁有的單例。你可以搜索「可可單身人士」瞭解更多信息。 – 2011-04-18 20:40:21

12

嘗試取消並取消設置-viewWillUnload中的代理人而不是-viewDidUnload。我懷疑它實際上卸載的時間窗口(在調用這兩個UIViewController方法之間)是可以被破壞的時間段。代表已經離開,但你還沒有告訴你的ASIHTTPRequest對象。

+6

在viewWillDissapear,這似乎已經做到了,至少我無法讓它崩潰。我做了,但添加了以下代碼,只是爲了確保: - (void)viewWillDisappear:(BOOL)animated {super viewWillDisappear:animated]; (隊列操作中的ASIHTTPRequest *請求){ [req clearDelegatesAndCancel]; [req setDelegate:nil]; [req setDidFailSelector:nil]; [req setDidFinishSelector:nil]; } [queue cancelAllOperations]; [queue setDelegate:nil]; } – 2011-04-18 18:18:18