Я считаю это ошибкой или, по крайней мере, слабостью в UIKit, но я уже потратил на это половину своего дня, поэтому я не собираюсь писать это с примером кода и сообщать об этом прямо сейчас Apple. Если кто-то еще захочет это сделать, я буду признателен.
Вот что я думаю, что происходит под капотом. У вас есть UITableViewController, назовем его myTable, в стеке UINavigationController, и этот стек навигации скрыт, потому что он находится на невыбранной вкладке или чем-то еще. Затем вы вызываете [myTable.tableView reloadData], и iOS ловко оптимизирует, не перезагружая данные сразу, потому что пользователь все равно не увидит их, если они находятся на скрытой вкладке. Вместо этого запрос на перезагрузку откладывается и сохраняется где-то для отображения представления. Но прежде чем это можно будет показать, вы вытаскиваете myTable из стека навигации. Когда отображается исходная вкладка myTable, выполняется запрос на перезагрузку, но его источника данных больше нет, поэтому это неверный доступ.
Теперь из моих тестов с подклассом UITableViewController, который использует автоматически предоставленное свойство tableView (не загружается из файла NIB), UITableView не освобождается при освобождении myTable, как в ситуации выше. Это было бы хорошо, за исключением того, что реализация по умолчанию для dealloc для UITableViewController не очищает свойство dataSource для UITableView (которое было установлено реализацией init по умолчанию).
Так что, возможно, есть несколько хороших обходных путей, например, откладывание запроса на reloadData самостоятельно, но самый простой из них, который я могу придумать, это поместить его в реализацию вашего подкласса UITableViewController:
- (void)dealloc {
...
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
[super dealloc];
}
Любая дополнительная мудрость будет приветствоваться.