按钮上的iOS6 UIViewControllerHierarchyInconsistency单击

时间:2012-10-16 07:09:44

标签: objective-c ipad ios-simulator ios6

我在iOS 6 iPad中面临问题

  1. 点击按钮 - >用UITable打开popover
  2. 选择一行 - > modalviewcontroller open。
  3. 解雇modalviewcontroller(工作正常)
  4. 然后再次单击按钮,按钮单击(第1步)
  5. 时应用程序崩溃

    此问题仅适用于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];
    

2 个答案:

答案 0 :(得分:5)

更密切地检查您的例外情况:

'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仍然存在,这就是为什么它在第二次运行而不是第一次运行时崩溃的原因。我猜想,在尝试创建新的popover之前,你的代码不会完全解除分配和销毁旧的popover;如果你确定这种情况发生,你可能会没事。

我还注意到,显然,你在两个弹出框中使用相同的listTable。你是否想懒洋洋地为每个popover创建这个listTable而不是保留它?

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

除此之外,你还没有为某人提供足够的代码来查看它并说明问题是什么:)但上述内容应该可以帮助你解决问题。

答案 1 :(得分:1)

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

不确定这是否能完全满足您的要求,但可能会避免层次结构不一致错误。