.navigationController popViewControllerAnimated:YES
从NSOperation
屏幕未正确更新并使弹出视图可见但显然已解除分配的位置调用时,我遇到了一个奇怪的问题。
详细信息:我有一个访问本地sqlite
数据库的列表视图。当点击一条记录时,它会显示该记录的详细视图并启动一个异步 NSOperation(在主线程上)以检查 XML 后端数据库以查看该记录在数据库中是否仍然可用。由于架构原因,我不会进入,我无法在列表视图上运行此操作,它必须在详细视图中。如果自上次同步后删除了记录,它会通知用户该记录已被删除,并popViewControllerAnimated
在共享应用程序委托上调用。理想情况下,这将弹出当前详细视图并返回到先前的列表视图。
错误:正确的视图实际上已在内存中弹出(已被释放),但仍显示在屏幕上。导航栏是空白的,但我可以点击“返回”按钮应该在的位置,它会在列表视图之前导航到开始屏幕,这意味着至少导航栏知道它应该在哪里,甚至如果它没有正确显示标题或后退按钮。主要问题是详细视图仍然可见并且可以与之交互,这会导致应用程序崩溃。例如,详细视图还显示 a 中的数据UITableView
,如果用户在表格中向下滚动,则会引发异常“-[xAccountDetailController tableView:cellForRowAtIndexPath:]:
消息已发送到已释放实例”
这让我相信细节控制器已经被popViewControllerAnimated
调用正确地释放了,但是如果表实际上调用了,那么显然有些东西仍然驻留在内存中cellForRowAtIndexPath
,即使它的视图控制器已经从导航控制器中弹出。
在“详细信息”视图中手动按下后退按钮(对于未在后端删除的记录)效果很好。
解决方法尝试:当我向 NSOperation 传递对详细视图控制器的引用时,我试图popViewControllerAnimated
直接从该视图的 navigationController 属性和共享应用程序委托调用。我还尝试弹出两个视图并将列表视图重新推送到 navigationController 上,但这会带来更令人不安的界面效果,其中根视图控制器和列表视图控制器似乎同时存在于导航栏中(标题相互覆盖而不是不存在)。我试图将 NSOperation 中存在的详细视图控制器的引用设置为 nil,但这没有任何作用。我尝试[detailView release]
在弹出之前调用 a ,但正如预期的那样,它在弹出时失败,因为它在发布之前只有 1 的保留计数。我'popToViewController
而且popToRootViewController
似乎没有任何效果。旧视图始终存在,导航栏是唯一似乎可以做任何事情的界面元素,即使那样,它也显示不正确。我也尝试过重新加载表格,因为我真的不介意视图是否保持可见(没有弹出),我只想清除数据——但表格由于某种原因不会重新加载数据。
想法:由于运行 NSOperation 的 operationQueue 是相关详细视图的属性,因此我确保在详细视图的 dealloc 中取消所有操作并将对 operationQueue 的引用设置为 nil。我还尝试确保其他对象中对该视图的所有引用都设置为 nil。直接从详细视图上的按钮调用popViewControllerAnimated
可以完美运行,所以一定是我从 NSOperation 调用该方法,在 NSOperationQueue 上运行,这是我想要弹出的详细视图的属性。某处的某些引用必须使该视图部分保持活动状态,但是当调用 pop 时,我似乎找不到任何仍在引用该视图的内容。
太多地方的代码太多了,无法在这里发布。
有什么想法吗?
抱歉问了这么长的问题,提前谢谢,
格雷格
编辑 1:我可以使用新的 UIViewController 在 NSOperation 之外轻松重现此问题。
在一种tableView:didSelectRowAtIndexPath
方法中,我调用以下内容:
xBaseViewController * vc = [[xBaseViewController alloc] initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:vc animated:YES];
[vc performSelectorOnMainThread:@selector(popView) withObject:nil waitUntilDone:YES];
在vc中,popView方法:
[self.navigationController popViewControllerAnimated:YES];
我认为这与保留计数或 NSOperation 无关。以这种方式弹出视图,我在做一些根本错误的事情吗?