1

概述的UITableView - moveRowAtIndexPath導致內存泄漏

  • 在iOS的項目,我有一個UITableView,我試圖移動UITableView中的一行。
  • 在我的模型,數據的順序已經改變,所以我想直觀地展現它在表上,這就是爲什麼我用爲了做到這一點,我創建UITableView的方法moveRowAtIndexPath:toIndexPath:
  • NSIndexPath我將傳遞給UITableView方法的實例。

當泄漏accurs

  • 當創建使用該方法indexPathForRow: section:(如在代碼段示出),然後將其moveRowAtIndexPath: toIndexPath:它泄漏傳遞給UITableView的方法的NSIndexPath實例。

注:

  • 我使用ARC(自動引用計數)
  • 的XCode 4.3.1
  • 我所使用的儀器(Xcode的菜單 - 產品>資料),以確定內存泄漏

代碼:(在UITableViewController裏面)

NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:newRow inSection:0]; //leaking 

[self.tableView beginUpdates]; 
[self.tableView moveRowAtIndexPath:originalIndexPath toIndexPath:newIndexPath]; //I think this causes the leak 
[self.tableView endUpdates]; 

步驟我試圖

  • 呼叫註釋出到方法moveRowAtIndexPath:originalIndexPath toIndexPath:,防止內存泄露
  • 我已經手動使用CFRelease(不知道這是一個很好的做法在自動參考計數環境中)

    CFRelease((__ bridg e void *)toIndexPath);

問題:

  • 爲什麼會發生這種情況?有沒有解決辦法?
  • 儀器的內存泄漏結果是否準確?
  • UITableView的方法moveRowAtIndexPath:originalIndexPath toIndexPath:有錯誤嗎?
  • CFRelease是一個選項嗎?如果CFRelease嘗試釋放已釋放的內存(請參閱上面的確切代碼),是否有安全的方法來防止應用程序崩潰。
+0

我不知道,如果儀器會顯示內存泄漏如果該對象已這是爲什麼這是一個評論,而不是一個答案。你有沒有嘗試在更新後運行[[NSGarbageCollector defaultInstance] collectExhaustively]? – 2012-03-20 02:21:58

+0

感謝您的回覆,我正在做一個iOS項目,所以我無法嘗試垃圾收集。糾正我,如果我錯了 – user1046037 2012-03-20 04:56:43

回答

1

您發佈的代碼不應導致ARC設置中的內存泄漏(對於該事件,也不應該沒有ARC)。

如果您的確懷疑有一個錯誤(例如UITableView無法釋放NSIndexPath對象),那麼您可以嘗試手動釋放它作爲臨時解決方法。但是,您確定在動畫完成後它不會釋放它嗎?即使你沒有動畫,也可能是indexPath對象直到空閒循環才被釋放(這對於GUI組件來說是很常見的,而且對於自動釋放對象也是很常見的)。

但是,爲了確認它確實是泄漏,請嘗試調查內存是否會隨着時間的推移而長時間增加(可能是因爲UITableView粘貼到其最新的indexPath對象,成爲一個問題)。另外,嘗試使用NSZombieEnabled環境變量集運行調試器。當您嘗試雙擊釋放對象時,這將檢測並進入調試器。

+0

非常感謝答覆,我趕上了另一個問題,我會嘗試NSZombieEnabled。 – user1046037 2012-03-21 06:56:39

1

我沒有足夠的代表添加評論,所以我必須添加一個答案。我也看到這個泄漏。我不使用ARC,並且我沒有使用beginUpdates/endUpdates將單個調用包裝到moveRowAtIndexPath:toIndexPath:每當我調用此方法時,Instruments聲明一個32字節的NSIndexPath泄漏。

調用NSIndexPath的indexPathForRow:inSection:應該返回一個不需要手動釋放的自動釋放對象。我懷疑moveRowAtIndexPath:toIndexPath:不正確地保留該對象,導致泄漏。

我添加了一些調試代碼來記錄調用moveRowAtIndexPath:toIndexPath之前和之後的NSIndexPath的retainCount:並獲得1之前(它是在一個自動發佈池,所以這是預期的)和5之後(絕對不是預期除非它已被添加到自動釋放池4次以上)

編輯:又見https://devforums.apple.com/message/639904(需要蘋果開發者帳戶)