【问题标题】:iOS6 UIViewControllerHierarchyInconsistency on Button clickiOS 6 UIViewController Hierarchy Inconsistency on Button click
【发布时间】:2012-10-06 05:35:10
【问题描述】:

我在 iOS 6 iPad 中遇到问题

  1. 点击按钮 -> 使用 UITable 打开弹出框
  2. 在选择一行时 -> modalviewcontroller 打开。
  3. 关闭 modalviewcontroller(它工作正常)
  4. 然后再次点击按钮,点击按钮时应用程序崩溃(第一步)

此问题仅在 iOS 6 中。它在 iOS 5、iOS 4.3 中运行良好

*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View <UITableView: 0xb847400; frame = (0 0; 185 104); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0xa469e50>; layer = <CALayer: 0xa469f00>; contentOffset: {0, 0}> is associated with <UIViewController: 0xa462f60>. Clear this association before associating this view with <UIViewController: 0xa5dac40>.'
*** First throw call stack:
(0x2769012 0x1d0be7e 0x2768deb 0xca1309 0xd385ac 0xd34a90 0x69b19 0x1d1f705 0xc56920 0xc568b8 0xd17671 0xd17bcf 0xd16d38 0xc8633f 0xc86552 0xc643aa 0xc55cf8 0x29a2df9 0x29a2ad0 0x26debf5 0x26de962 0x270fbb6 0x270ef44 0x270ee1b 0x29a17e3 0x29a1668 0xc5365c 0x24ca 0x23d5)
libc++abi.dylib: terminate called throwing an exception

添加代码

listTable.frame = CGRectMake(0, 0, listWidth, listItemHeight*[listArray count]-1);
UIViewController* popoverContent = [[UIViewController alloc] init];
popoverContent.view = listTable;
popoverContent.contentSizeForViewInPopover = CGSizeMake(listWidth, listItemHeight*[listArray count]);
listPopOver = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[listPopOver setDelegate:self];
[listPopOver setPopoverContentSize:listTable.frame.size];
[listPopOver presentPopoverFromRect:self.frame inView:self.superview permittedArrowDirections:arrowDirection animated:YES];
[listTable reloadData];
[popoverContent release];

【问题讨论】:

  • 很可能您正在释放弹出框,这是一个需要解决的简单问题,您能否展示调用和关闭弹出框的代码?
  • 我的代码在线崩溃popoverContent.view = listTable;

标签: objective-c ipad ios-simulator ios6


【解决方案1】:

您可以将listTable 添加为子视图,而不是替换popoverContent 的视图吗?

不确定这是否能完全实现您所寻找的,但它可能会避免层次结构不一致错误。

【讨论】:

    【解决方案2】:

    更仔细地检查您的异常:

    'UIViewControllerHierarchyInconsistency', reason:
    'A view can only be associated with at most one view controller at a time!
    View UITableView: 0xb847400; frame = (0 0; 185 104); clipsToBounds = YES;
    autoresize = W+H; gestureRecognizers = NSArray: 0xa469e50; layer = CALayer: 0xa469f00;
    contentOffset: {0, 0} is associated with UIViewController: 0xa462f60.
    Clear this association before associating this view with UIViewController: 0xa5dac40.'
    

    具体来说:

    A view can only be associated with at most one view controller at a time!
    View UITableView: 0xb847400
    is associated with
    UIViewController: 0xa462f60. 
    Clear this association before associating this view with 
    UIViewController: 0xa5dac40.
    

    这意味着你有一个视图控制器,它的.view 属性被设置为你的listTable 对象。然后,在不破坏该关联的情况下,您使用另一个视图控制器并尝试将其.view 属性设置为 listTable 对象。这违反了视图层级规则,Apple 从 iOS 6.0 开始更加严格地执行该规则,以至于现在它会引发异常并使您的应用程序崩溃。

    所以这里真正的问题是,您使用同一个 listTable 对象和两个视图控制器,特别是 popoverContent。这意味着当您的代码第二次执行时,您的旧 popoverContent 仍然存在,这就是它在第二次运行而不是第一次运行时崩溃的原因。我猜想在尝试创建新弹出框之前,您的代码不会以某种方式完全释放和销毁旧弹出框;如果您确保发生这种情况,您可能会没事。

    我还注意到,显然,您对两个弹出框都使用了相同的 listTable。您是否想为每个弹出框懒惰地创建这个 listTable 而不是保留它?

    如果您想进行更多调查,可以在代码中设置断点并打印不同视图和视图控制器的描述,使用 po 命令查看哪些十六进制地址与随后出现的地址匹配您的异常,并获取有关该问题的更多信息。或者,您甚至可以直接使用十六进制地址打印描述:例如po 0xa469e50(但可能需要进行类型转换)。

    除此之外,您还没有真正提供足够的代码供某人查看并说出问题所在:) 但以上内容应该可以帮助您解决问题。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多