2010-06-16 170 views
0

問題出在這裏 - 我遵循Apple延遲加載的圖像示例代碼來處理我的圖形表。它效果很好。但是,我的懶加載圖像表正在堆疊在導航控制器中,以便您可以移入和移出菜單。雖然所有這些都有效,但當我移動到一個表格後,使用「返回」按鈕立即移出它,我會發生持久性崩潰。這似乎是網絡連接加載內容沒有被正確關閉或回撥給他們的發佈代表的結果。現在,我嘗試瞭解這一點,並仔細設置所有代表爲零,並在釋放菜單之前在所有打開的網絡連接上調用close。但是,我仍然收到錯誤。此外 - 我的整個應用程序代碼短貼在這篇文章中,我不能真正發佈一個特定的代碼片段,說明這種情況。停止延遲加載圖像?

我想知道是否有人對我可能錯過的任務有想法?除了關閉網絡連接並將其設置爲零之外,是否需要執行任何操作來關閉網絡連接?另外,我對調試工具不熟悉 - 任何人都可以提出一個很好的工具來觀察網絡連接並查看是什麼導致它們失敗?

謝謝!

回答

2

你是否通過調試器(Cmd-Y)運行它?它是否停在發生事故的地方?這應該顯示你在代碼中發生問題的地方。我敢打賭,這個問題與過度釋放某些東西有關,而不是清理連接。您是否獲得EXC_BAD_ACCESS?檢查任何代表並確保它們在零時--viewWillDisappear被調用。這樣,如果有任何事情試圖回撥給委託人,它將只是一個無操作。

您可能還想嘗試啓用殭屍(NSZombieEnabled),它會告訴您什麼時候再次訪問了已釋放的對象。這對於發現過度釋放的對象非常有幫助。

+0

非常感謝,這是一個非常有用的提示!那殭屍功能是非常有用的......我以前在XCode文檔中提到過殭屍,但我不知道他們到現在爲止做了什麼。 – bigmac 2010-06-16 17:51:20

+1

格雷格,如果它是一個有用的提示你爲什麼不投票並接受它? – Terry 2010-06-16 19:34:30

0

如果您正在執行任何異步功能(網絡請求,核心位置更新等),那麼運行風險是您的視圖控制器是該操作的委託時會在異步函數返回時解除分配。即退出視圖並將代表目標從後臺進程中移走。我已經處理了好幾次。

這就是你要做的。使用ASIHTTPRequest庫(無論如何你都應該這樣做 - 這太棒了)。創建一個合成屬性來保存您的請求。然後在viewWillDisappear,根據您的請求調用-cancel。爲了安全起見,我還將其代表設置爲零,但這應該是不必要的。

下面是你想做什麼的草圖。注意我在這裏輸入了這個,沒有語法檢查它或任何東西。

@implementation MyViewController 

@synthesize req //this is an ASIHTTPRequest *req. 

-(void)viewDidLoad 
{ 
    //make an NSURL object called myURL 
    self.req = [ASIHTTPRequest requestWithURL:myURL]; 
    self.req.delegate = self; 
    [self.req startAsynchronous]; 
} 

-(void)viewWillDisappear 
{ 
    [self.req cancel]; 
} 

-(void)requestFinished:(ASIHTTPRequest *)request 
{ 
    NSString *string = [request responseString]; 
} 
+0

感謝異步庫上的提示。我一定會爲我的(不可避免的)下一個iPhone項目檢查一下......我已經完成了我所有的網絡活動,這次我使用Apple示例代碼作爲指導,並且實施了大量從我的熟悉的Flash AS3工作。它工作得很好,我學到了很多東西!然而,在未來使生活變得更加容易將會很好...... – bigmac 2010-06-16 17:59:53

+0

原則依然存在 - 在您的viewDidUnload中,您應該將NSURLRequest對象的委託設置爲nil。給nil的消息是一個沒有錯誤的無操作(這是很好的知道,如果你有一種方法,似乎什麼也不做!),所以它是很好的踐踏你的委託鏈接,所以它不會嘗試回撥一個代言人,已經過時了。 – 2010-06-16 18:39:29

1

啊哈......大量的殭屍狩獵後(感謝,馬特龍),我發現,這個問題在蘋果的LazyTableImages示例代碼中的錯誤造成的。這個例子提供了取消所有圖像加載,我變成了一個通用的方法stopAllImageLoads以下實現...

RootViewController.mLazyTableImages示例代碼:

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 

    // terminate all pending download connections 
    NSArray *allDownloads = [self.imageDownloadsInProgress allValues]; 
    [allDownloads performSelector:@selector(cancelDownload)]; 
} 

有錯誤在最後上述方法的一行,其中performSelector在對象數組上被調用。上面的實現調用數組本身的選擇器,而不是數組中的每個對象。因此,最後一行應該是這樣的:

[allDownloads makeObjectsPerformSelector:@selector(cancelDownload)]; 

一旦該行被更改,其他所有內容都會落空。事實證明,我並沒有打電話給我的stopAllImageLoads方法,我的意思是 - 我一度禁用了它,因爲它造成了錯誤。一旦恢復原狀,內存問題就會清除,因爲在表代表發佈之前,圖像加載已成功取消。

謝謝大家的幫助。