弹出到根视图控制器而不会导致表视图的动画崩溃 [英] Pop to root view controller without animation crash for the table view

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

问题描述

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

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

例如。 tab1,tab2和tab3。

导航堆栈中的第二个视图控制器(tab2VC2)有一个tableView。
单击tab2,在tab2中显示VC,然后点击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


[UserDetailVC
tableView:cellForRowAtIndexPath:]:
消息发送到解除分配的实例
0xe0a23b0

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

如果我用动画popToRootVC那么没关系。我发现tab2VC2中的viewDidAppear被调用,其中tableView.reloadData被调用,然后是dealloac,似乎在此期间reloadData开始工作,表被释放。在动画的情况下,它需要一些时间,所以它不会崩溃。但是没有动画,就会崩溃。
你认为,这是一个iPhone的bug吗?或者我做错了?由于pop到root控制器有一个没有动画的选项,它应该可以工作,不是吗?

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的一个弱点,但我已经把它的一半时间都吹了,所以我不打算用示例代码写出来并立即报告给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,让我们在UINavigationController的堆栈上调用它myTable,并且导航堆栈是隐藏的,因为它位于未选择的选项卡或其他任何位置。然后,你调用[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];
}

任何额外的智慧都是最受欢迎的。

Any additional wisdom would be most welcome.

这篇关于弹出到根视图控制器而不会导致表视图的动画崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆