转换为使用 iOS 8 Popover Segues 时 UISplitViewController 崩溃
Posted
技术标签:
【中文标题】转换为使用 iOS 8 Popover Segues 时 UISplitViewController 崩溃【英文标题】:UISplitViewController Crash when converting to use iOS 8 Popover Segues 【发布时间】:2014-09-30 00:55:53 【问题描述】:我有一个 UISplitViewController,它是在 ios 6/7 天从模板设置的。我试图隐藏它以使用新的 iOS 8 UISplitViewController 工具使我的应用程序能够在 iPhone 上运行。但是,我遇到的问题都发生在使用 XCode 6 Beta 5 的 iPad 2 模拟器上。
之前我使用此代码将所选项目项传递到详细信息视图:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
self.detailViewController.detailItem = [[self fetchedResultsController] objectAtIndexPath:indexPath];
基于 iOS 8 的示例,应将其更改为 segue 以使其能够在不同大小的类和 UISplitViewControllerDisplayModes 中工作。所以我将我的单元作为源和我的详细导航控制器作为我的 segue 的目标,注释掉上面的 tableview:didSelectRowAtIndexPath
位,并实现了这个 prepareForSegue 代码:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([segue.identifier isEqualToString:@"showDetail"])
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
self.detailViewController = (TWLDetailViewController *)[[segue destinationViewController] topViewController];
self.detailViewController.detailItem = [[self fetchedResultsController] objectAtIndexPath:indexPath];
我第一次在我的主视图中选择一行时,一切似乎都按预期工作(我看到了详细视图),但是我选择的下一个单元格导致试图解决一个已释放实例的崩溃,本质上是:*** -[DetailViewController respondsToSelector:]: message sent to deallocated instance 0x7a37a030
(我使用的是 ARC BTW,所以这里没有手工编码的保留/释放错误。)
我在 SO 上查找了一些 similar issues,并尝试在 Instruments 中使用 Zombie 分析器,如下所示(右键或控制单击图像并在新选项卡中查看它以查看完整大小):
您可以清楚地看到它正在尝试解决一个不可用的引用,因为“RefCt”变为零。我没有太多使用 Instruments 或类似调试工具的经验,但我不清楚我需要更改什么来解决这个问题,特别是因为它与 tableview:didSelectRowAtIndexPath
一起使用。
所以我的问题是:当我在明细项目之间切换时,如何更改我的主代码或明细代码以正确解除分配?对于奖励积分,很高兴知道为什么它使用以前的 tableview:didSelectRowAtIndexPath
运行良好但在 segue 上崩溃了。如果您需要查看代码的其他部分或 Instruments 跟踪,请告诉我;我很乐意分享。
【问题讨论】:
【参考方案1】:您必须设置拆分视图控制器委托以准备继续:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([segue.identifier isEqualToString:@"showDetail"])
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
self.detailViewController = (TWLDetailViewController *)[[segue destinationViewController] topViewController];
self.detailViewController.detailItem = [[self fetchedResultsController] objectAtIndexPath:indexPath];
self.splitViewController.delegate = self.detailViewController;
也在 didSelectRowAtIndexPath 中设置:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
self.detailViewController = [[self.splitViewController.viewControllers lastObject] topViewController];
self.splitViewController.delegate = self.detailViewController;
【讨论】:
谢谢霍尔格。我认为这很容易。以上是关于转换为使用 iOS 8 Popover Segues 时 UISplitViewController 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 9 上关闭由 segue 创建的 Popover
iOS 6 Storyboard Segue 风格 Popover 与 UIPopoverController 目标崩溃
从 Modal/Popover 展开 Segue 导致开始/结束外观转换的调用不平衡
在 prepareForSegue 上为 Popover Segue 传递数据:iOS 5 中的奇怪行为
从另一个 Popover 中关闭显示为 Popover segue 的 ViewController
iOS 7 - PopOver 中的 UITableViewController 可以找到带有错误的 segue Receiver(UITableViewController) has no segu