kar*_*rim 12 objective-c uikit uinavigationcontroller ios
我在标签栏控制器中有3个视图控制器.单击任何选项卡会在导航堆栈中加载其根视图控制器.
例如tab1,tab2和tab3.
导航堆栈中的第二个视图控制器(tab2VC2)有一个tableView.单击tab2,在tab2中显示VC,然后点击tab1,尝试转到rootVC.然后应用程序崩溃说
[UserDetailVC tableView:cellForRowAtIndexPath:]:发送到解除分配的实例0xe0a23b0的消息
如果我用动画popToRootVC那么没关系.我发现tab2VC2中的viewDidAppear被调用,其中tableView.reloadData被调用,然后是dealloac,似乎在此期间reloadData开始工作,表被释放.在动画的情况下,它会有一些时间,所以它不会崩溃.但没有动画,就会崩溃.你觉得,这是一个iPhone的bug吗?或者我做错了?由于pop到root控制器有一个没有动画的选项,它应该可以工作,不是吗?
#pragma mark Tab bar controller delegate
- (void)tabBarController:(UITabBarController *)tbController didSelectViewController:(UIViewController *)viewController {
int i = tbController.selectedIndex;
NSArray *mycontrollers = tbController.viewControllers;
[[mycontrollers objectAtIndex:i] popToRootViewControllerAnimated:NO];
}
Run Code Online (Sandbox Code Playgroud)
Jes*_*sen 36
我认为这是一个错误,或者至少是UIKit的一个弱点,但我已经把它的一半时间都吹了,所以我不打算用示例代码编写它并立即报告给Apple.如果其他人想这样做,我将不胜感激.
这就是我认为在幕后发生的事情.你有一个UITableViewController,让我们在UINavigationController的堆栈上调用它myTable,并且导航堆栈是隐藏的,因为它位于未选择的选项卡或其他任何位置.然后,你调用[myTable.tableView reloadData],并且通过不立即重新加载数据来巧妙地优化iOS ,因为如果它在隐藏的选项卡上,用户将无法看到它.相反,重新加载请求被延迟并存储在显示视图的某处.但在显示之前,您可以将myTable从导航堆栈中弹出.当myTable的原始选项卡显示时,重载请求会被执行,但是它的dataSource不再存在,所以这是一个糟糕的访问.
现在,我使用UITableViewController的子类进行测试,该子类使用自动提供的tableView属性(不是从NIB文件加载),当myTable如上面的情况解除分配时,UITableView不会被释放.这没关系,除了UITableViewController的默认dealloc实现没有清除UITableView的dataSource属性(由init的默认实现设置).
所以,可能有一些很好的解决方法,比如自己将请求推迟到reloadData,但我能想到的最简单的方法是将它放在UITableViewController子类的实现中:
- (void)dealloc {
...
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
任何额外的智慧都会受到欢迎.
| 归档时间: |
|
| 查看次数: |
5707 次 |
| 最近记录: |