2014-10-09 209 views
0

我一直有問題與UITableView發送消息交易委託。 當擁有tableView的UIViewController中的dealloc被調用時,tableView仍然是活着的,並且tableView正在向它的委託發送消息。通過在tableView的所有者在dealloc中釋放tableview時設置delegate = nil來解決此崩潰問題。如果內存管理是正確的,我相信這不是必須的。如何找到誰正在保留一個對象?

我想知道誰是保留tableView的方法。

有什麼辦法可以弄清楚嗎?

謝謝!

回答

0

用儀器啓動項目(菜單產品 - >配置文件 in Xcode)並選擇泄漏。它將記錄每個已創建,保留,釋放,自動釋放,釋放的對象。你甚至可以在那裏搜索一個內存地址。所以你需要做的就是獲得你的對象的內存地址的方法,例如你可以打印它到控制檯。大多數人不知道,但你可以從儀器中查看控制檯:

enter image description here

2

您的tableView在其代理清理後繼續處理;請記住,代表被分配到weak參考屬性,因此不被UITableView保留。如果您正在摺疊ViewControllerUITableView仍在加載元素,則會看到此次崩潰。如果正在釋放的類是委託,最好在dealloc中分配.delegate = nil

+0

「記住,代表們被分配給弱引用屬性」 - 委派的UITableView設置爲@財產(非原子,分配) id 委託,這就是爲什麼tableView仍然可以發送消息到已處理的對象。 – kazuochi 2014-10-10 14:41:34

+0

這是正確的 - 'UITableView'是在ARC之前創建的,所以你可以考慮'assign' =='weak'和'retain' =='strong'。當你的'UITableViewDelegate'被釋放後,'UITableView'不再能夠發送消息給對象,因爲該對象不存在。但是,它可以嘗試將消息發送到之前由'UITableViewDelegate'佔用的內存地址處的對象;這通常會導致EXC_BAD_ACCESS。 – 2014-10-10 15:02:47

2

此崩潰通過在tableView的所有者在dealloc中釋放tableview時設置delegate = nil來解決。如果內存管理是正確的,我相信這不是必須的。

,往往是真實的今天,是因爲代表們經常宣稱weak,這意味着當底層對象被釋放,它們會自動設置爲nil。但UITableView比這個更舊。它來自弧前幾天及其委託聲明:

@property(nonatomic, assign) id<UITableViewDelegate> delegate 

因此,如果委託被釋放,UITableView將指向未分配的內存。

這種類型的崩潰通常意味着當您不在屏幕上時嘗試更新您的tableview。根據我的經驗,最常見的原因是當你不應該觀察通知時。您希望確保您觀察到viewWillAppear:中的通知,並在viewDidDisappear:期間刪除所有觀察結果。同樣,當你離開屏幕時,你不應該觀察KVO(但我更經常發現這種崩潰表明NSNotification)。

您還應該確保除委託以外的任何對象都不能直接訪問tableview。沒有人應該從視圖/代表關係之外調用reloadData等。沒有人應該訪問委託人的IBOutlet屬性。這些事情導致這些崩潰。委託人以外的任何人都不應該參考表格視圖。

當然,確保你沒有更新後臺線程上的表視圖。這可能不是這種情況;它往往會導致其他類型的崩潰。但這是另外一種可能性。