I have 3 view controller in a tab bar controller. Clicking on any tab loads its root view controller in the navigation stack.
e.g. tab1, tab2, and tab3.
The 2nd vi
I consider this a bug or at least a weakness in UIKit, but I've already blown half my day on it, so I'm not going to write it up with example code and report it to Apple right now. If someone else wants to do that, I would appreciate it.
Here's what I think is going on under the hood. You have a UITableViewController, let's call it myTable, on the stack of a UINavigationController, and that navigation stack is hidden because it's on an unselected tab or whatever. Then, you call [myTable.tableView reloadData], and iOS cleverly optimizes by not reloading the data right away, because the user won't be seeing it anyway if it's on a hidden tab. Instead, the reload request is deferred and stored somewhere for when the view is shown. But before it can be shown, you pop myTable off the navigation stack. When myTable's original tab is shown, the reload request gets executed, but its dataSource is no longer there, so it's a bad access.
Now from my tests with a subclass of UITableViewController that uses the automatically provided tableView property (not loaded from a NIB file), the UITableView is not being deallocated when myTable deallocates as in the situation above. That would be fine, except the default dealloc implementation for UITableViewController does not clear the dataSource property of the UITableView (which was set by the default implementation of init).
So, there are probably a couple good workarounds, like deferring the request to reloadData yourself, but the simplest one I can think of is putting this in the implementation of your UITableViewController subclass:
- (void)dealloc {
...
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
[super dealloc];
}
Any additional wisdom would be most welcome.