弹出到根视图控制器,没有表视图的动画崩溃

Pop to root view controller without animation crash for the table view(弹出到根视图控制器,没有表视图的动画崩溃)

本文介绍了弹出到根视图控制器,没有表视图的动画崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在标签栏控制器中有 3 个视图控制器.单击任何选项卡会在导航堆栈中加载其根视图控制器.

I have 3 view controller in a tab bar controller. Clicking on any tab loads its root view controller in the navigation stack.

例如选项卡 1、选项卡 2 和选项卡 3.
导航堆栈 (tab2VC2) 中的第二个视图控制器有一个 tableView.点击tab2 show VC in tab2,然后点击tab1,尝试进入它的rootVC.然后应用程序崩溃说

e.g. tab1, tab2, and tab3.
The 2nd view controller in the navigation stack (tab2VC2), has a tableView. Click on tab2 show VC in tab2, then tap on tab1, tries to go to its rootVC. Then the app is crashing saying

[用户详细信息VC表视图:cellForRowAtIndexPath:]:发送到已释放实例的消息0xe0a23b0

[UserDetailVC tableView:cellForRowAtIndexPath:]: message sent to deallocated instance 0xe0a23b0

如果我用动画 popToRootVC 那就没问题了.我发现在 tab2VC2 中调用了 viewDidAppear,其中调用了 tableView.reloadData,然后是 dealloac,似乎与此同时 reloadData 开始工作,表被释放.在动画的情况下,它需要一些时间,所以它不会崩溃.但是没有动画,它就会崩溃.你认为,它是一个 iPhone 错误?还是我做错了?既然弹出到根控制器有一个没有动画的选项,它应该可以工作,不是吗?

If I popToRootVC with animation then its okay. I found viewDidAppear in the tab2VC2 is called where the tableView.reloadData is called, then dealloac, seems in the meantime reloadData starts working, the table is released. in case of animation, it gets some time, so it dont crash. But without animation, it is crashing. Do you think, its an iPhone bug? or I am doing wrong? Since pop to root controller have an option without animation, it should work, not it?

#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];
}

推荐答案

我认为这是 UIKit 的一个 bug 或者至少是一个弱点,但是我已经吹了大半天了,所以我不会写使用示例代码并立即将其报告给 Apple.如果其他人想这样做,我将不胜感激.

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.

这就是我认为幕后发生的事情.你有一个 UITableViewController,我们称它为 myTable,在 UINavigationController 的堆栈上,并且导航堆栈是隐藏的,因为它位于未选择的选项卡或其他任何东西上.然后,您调用 [myTable.tableView reloadData],iOS 巧妙地通过立即重新加载数据进行优化,因为如果它位于隐藏选项卡上,用户无论如何都不会看到它.取而代之的是,重新加载请求被延迟并存储在某个地方以供显示视图时使用.但在它可以显示之前,您将 myTable 从导航堆栈中弹出.当显示 myTable 的原始选项卡时,会执行重新加载请求,但它的 dataSource 不再存在,因此访问不正确.

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.

现在,根据我对 UITableViewController 子类的测试,该子类使用自动提供的 tableView 属性(不是从 NIB 文件加载的),当 myTable 像上述情况那样解除分配时,UITableView 不会被解除分配.这很好,除了 UITableViewController 的默认 dealloc 实现不会清除 UITableView 的 dataSource 属性(由 init 的默认实现设置).

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).

所以,可能有几个很好的解决方法,比如自己推迟 reloadData 的请求,但我能想到的最简单的方法是将它放在 UITableViewController 子类的实现中:

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];
}

欢迎任何额外的智慧.

这篇关于弹出到根视图控制器,没有表视图的动画崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:弹出到根视图控制器,没有表视图的动画崩溃

基础教程推荐