![](/img/trans.png)
[英]presentViewController crashes with EXC_BAD_ACCESS on iOS 8
[英]UITableView crashes on iOS 9 when endUpdates is called with EXC_BAD_ACCESS
在用戶升級到iOS 9后,我們注意到一系列錯誤訪問( EXC_BAD_ACCESS
)崩潰,這些崩潰對於仍在iOS 8上的用戶來說不會出現。當我們在UITableView上調用endUpdates
時會發生這種情況。
崩潰日志包括以下原因:
在當前參數寄存器中找到的選擇器名稱:numberOfRowsInSection:
在當前參數寄存器中找到的選擇器名稱:indexPathForRowAtGlobalRow:
堆棧跟蹤#1:
1 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke + 92
2 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke1007 + 224
3 UIKit -[UITableView _updateWithItems:updateSupport:] + 2556
4 UIKit -[UITableView _endCellAnimationsWithContext:] + 12892
[...]
堆棧跟蹤#2:
1 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke + 100
2 UIKit -[UITableViewRowData globalRowForRowAtIndexPath:] + 102
3 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke1007 + 182
4 UIKit -[UITableView _updateWithItems:updateSupport:] + 2300
5 UIKit -[UITableView _endCellAnimationsWithContext:] + 10552
我們能夠重新解決這個問題,但是沒有任何關於如何修復它的線索。
當您的UITableView沒有導致endUpdates與EXC_BAD_ACCESS崩潰的行時,看起來iOS9中存在一個錯誤。 要解決此錯誤,您必須在調用beginUpdates之前調用tableView reloadData。
從Claudio Redi指導我的線程: iOS9 iPad UITableView Crash(EXC_BAD_ACCESS)在第1部分插入 ,我已經實現了在調用[tableView beginUpdates];
之前添加的以下解決方法[tableView beginUpdates];
if ([[NSProcessInfo processInfo] operatingSystemVersion].majorVersion >= 9)
{
// there's a bug in iOS9 when your UITableView has no rows that causes endUpdates to crash with EXC_BAD_ACCESS
// to work around this bug, you have to call tableView reloadData before calling beginUpdates.
BOOL shouldReloadData = YES;
NSInteger numberOfSections = [tableView.dataSource numberOfSectionsInTableView:tableView];
for (NSInteger section = 0; section < numberOfSections; section++)
{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] > 0)
{
// found a row in current section, do not need to reload data
shouldReloadData = NO;
break;
}
}
if (shouldReloadData)
{
[tableView reloadData];
}
}
嘗試在beginUpdates()和endUpdates()調用之間執行多個插入,刪除或重新加載操作時遇到此錯誤,如此
tableView.beginUpdates()
tableView.deleteRows(at: [deletePaths], with: .fade)
tableView.insertRows(at: [insertPaths], with: .fade)
tableView.endUpdates()
我能夠通過調用解決問題
performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil)
而不是使用開始和結束調用,例如。
self.tableView.performBatchUpdates({
self.tableView.deleteRows(at: [deletePaths], with: .fade)
self.tableView.insertRows(at: [insertPaths], with: .fade)
}, completion: nil)
我也面臨這個問題,上面在表視圖上調用reloadData()
的答案確實解決了這個問題,但這並不理想,因為與更新相關的動畫由於重新加載而不流暢。
問題的根源是我在表視圖上以編程方式調用了selectRow(at indexPath: IndexPath?, animated: Bool, scrollPosition: UITableView.ScrollPosition)
,用於調用方法時的無效索引路徑。 (表格視圖中的更新是展開/折疊一個部分以顯示行內或行中的行,我有時會在折疊部分中選擇一行)。 在為表視圖中看不到的索引路徑選擇行時,此行為不會導致崩潰,但是在選擇無效索引路徑后更新beginUpdates(
)和endUpdates()
之間的UITableView
時,會發生崩潰在endUpdates()
調用時使用EXC_BAD_ACCESS。 在調用selectRowAt:
之前添加一個檢查selectRowAt:
以確保索引路徑可見/有效,在編程選擇解決崩潰之前無需調用reloadData()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.