2011-07-28 212 views
3

已解決(我認爲):設置ASIHTTPRequest委託/ NSOperationQueue委託在vc彈出後(在dealloc中)爲零。ASIHTTPRequest和殭屍...

在我開始之前,this的問題是類似的,但不一樣。

我的應用程序非常接近發行版,但是這是在整個開發過程中唯一存在的持續性錯誤。它也是向某人演示應用程序時發生的唯一錯誤,並且由於此錯誤導致終止應用程序,所以非常尷尬。如果有人能找到解決方案(好),我會獎勵一個體面的大小獎金。


開始的問題:

基本上,當ASIHTTPRequest試圖調用的requestFinished選擇器,到一個對象,它是一個殭屍發生這種錯誤。

從環顧四周,看起來ASIHTTPRequest在向殭屍發送選擇器時會將它發送給一個不是殭屍的類似對象。我聽說它將選擇器發送給它要發送給它的控制器的CALayer是非常常見的,並且還將它發送給我的UINavigationButton!?無論如何,這樣做的效果是它會拋出異常。

問題發生ASIHTTPRequest類的內部時,它試圖將「requestFinished」選擇撥打:

[queue performSelector:@selector(requestFinished:) withObject:self]; 

這行代碼是一個失敗的 - 令我百思不解的是爲什麼呢?在我所鏈接的問題上,OP表示他們通過從視圖控制器調用[self retain]來修復它。當然,這是不正確的?

結構

的方式我ASIHTTPRequest的工作,是他們被添加到downloadQueue,(NSOperationQueue),它位於我的應用程序委託中。我的應用程序的結構/風格主要基於this sample code,它與flickr RSS提要非常相似。

我的應用程序使用ASIHTTPRequest的部分是網絡攝像頭查看器。它有一個帶有表格視圖的導航控制器,顯示三個網絡攝像頭。這些圖像是JPEG,每30秒更新一次靜態文件(在遠程服務器上)。此表視圖中的單元格是自定義的,並且每個單元都加載它們自己的ASIHTTPRequest。單元格下載它們各自的圖像並顯示它們。

這裏是我創建的方法被稱爲每個我的細胞:

- (void)loadURL:(NSURL *)url { 
    ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:url]; 
    [request setDelegate:self]; 
    [request setDidFinishSelector:@selector(requestDone:)]; 
    [request setDidFailSelector:@selector(requestWentWrong:)]; 
    NSOperationQueue *queue = [[MyAppDelegate sharedAppDelegate] downloadQueue]; 
    [queue addOperation:request]; 
    [spinner startAnimating]; 
    [self addSubview:spinner]; 
    [request release]; 
} 

當這些單元中的一個被選中,它需要用戶的詳細視圖,其中ASIHTTPRequest的另一個實例是加載,它下載所選攝像頭的圖像。

如何錯誤被觸發

在正常的「沉穩」我的應用程序的使用,它的行爲罰款。在這些視圖之間發生快速推送和彈出時(在根網絡視圖和詳細網絡視圖視圖之間)會出現問題。如果您輸入詳細信息視圖,進度欄開始移動並且再次彈出到根目錄,則通常會發生這種情況。這使我相信,因爲控制器不活動,當ASIHTTPRequest完成時,它試圖調用控制器,它失敗。

崩潰日誌

Exception Type: EXC_BAD_ACCESS (SIGBUS) 
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000480 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib     0x30183f24 objc_msgSend + 24 
1 iCompton      0x0003c4d4 0x1000 + 242900 
2 CoreFoundation     0x35ea3f72 -[NSObject(NSObject) performSelector:withObject:] + 18 
3 iCompton      0x00029082 0x1000 + 163970 
4 CoreFoundation     0x35ea3f72 -[NSObject(NSObject) performSelector:withObject:] + 18 
5 Foundation      0x33fd3e66 __NSThreadPerformPerform + 266 
6 CoreFoundation     0x35ebc8ca __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 8 
7 CoreFoundation     0x35e8cec6 __CFRunLoopDoSources0 + 378 
8 CoreFoundation     0x35e8c6f2 __CFRunLoopRun + 258 
9 CoreFoundation     0x35e8c504 CFRunLoopRunSpecific + 220 
10 CoreFoundation     0x35e8c412 CFRunLoopRunInMode + 54 
11 GraphicsServices    0x35261d1c GSEventRunModal + 188 
12 UIKit       0x33865574 -[UIApplication _run] + 580 
13 UIKit       0x33862550 UIApplicationMain + 964 
14 iCompton      0x00002b92 0x1000 + 7058 
15 iCompton      0x00002b44 0x1000 + 6980 

  • 感謝如果你讀到這裏!如果你回答
  • 賞金,如果你解決我的問題:)

回答

6

如果您輸入詳細信息視圖,進度欄開始移動,並且您再次彈出到根目錄,則通常會發生這種情況。這使我相信,因爲控制器不活動,當ASIHTTPRequest完成時,它試圖調用控制器,它失敗。

我認爲你對此正確。

當你彈出到根控制器(或任何其他控制器)時,你應該試圖取消ASIHTTPRequest。在取消請求之前,您應該將其delegate設置爲零;或者您可以使用clearDelegatesAndCancel

可能這需要您在視圖控制器中保留對請求的引用,但這應該不成問題。

一個有趣的S.O.關於檢測UIViewController被彈出的問題/回答是here

+0

嗨,沒關係,我可以簡單地清除請求,因爲每個網絡攝像頭都使用相同的細節控制器,所以嘗試保存請求將毫無意義。無論如何,你如何檢測流行(不只是viewWillDisappear)... –

+0

我不明白,如果你可以取消請求,無論如何我編輯我的答案,添加有關檢測流行的信息... – sergio

+0

對不起,我的意思是通過'甩垃圾請求'去除代表團 –

0

你不應該在現場的應用程序使用NSZombieEnabled

  • 感謝甚至更多,內存是永遠不會釋放。您在開發時需要關閉它。快速推拉可能會耗盡記憶,引發記憶警告,並導致事情被釋放和釋放。直到您發佈崩潰日誌之前,我們不會確定。

  • +0

    我只通過儀器測試過殭屍......我只是使用術語殭屍來指稱過度釋放的對象。現在將發佈崩潰日誌。 –

    0

    以下是我解決了這個問題:在你的viewController的dealloc方法設置任何優秀ASIHTTPRequest S的delegatenil

    這從將消息發送到didFinishSelector S,小號等上的viewController所述的viewController被彈出後從導航堆棧和dealloc「d防止優秀ASIHTTPRequest秒。

    請記住:在ASIHTTPRequest方法cancelAllOperations可能調用異步。在這種情況下,可以在不再存在的viewController上調用選擇器