iOS6 UIViewControllerHierarchyInconsistency on But

2019-08-20 05:27发布

问题:

I facing issue in iOS 6 iPad

  1. On button click -> open popover with UITable
  2. On select a row -> modalviewcontroller open.
  3. dismiss modalviewcontroller (it works fine)
  4. Then again click on button, app crash on button click (1st step)

this issue is only in iOS 6. It works fine in 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

Adding Code

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];

回答1:

Check out your exception more closely:

'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.'

Specifically:

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.

What this means is that you had a view controller, and it's .view property was set to your listTable object. Then, without destroying that association, you took another view controller and tried to set its .view property to the listTable object. This is a violation of the view hierarchy rules, which Apple is enforcing more heavily as of iOS 6.0, to the point where it now throws an exception and crashes your app.

So the real problem here is that you are using the same listTable object with two view controllers, specifically popoverContent. This means that your old popoverContent is still in existence when your code executes a second time, which is why it crashes on the 2nd run and not the first. I would guess that somehow your code is not fully deallocating and destroying your old popover before the new one is trying to be created; if you make sure this happens you might be fine.

I also notice that, apparently, you are using the same listTable for both popovers. Do you perhaps want to lazily create this listTable for each popover instead of keeping it around?

If you want to investigate things more, you can set a breakpoint in your code and print descriptions of your different views and view controllers, using the po command, to see what hex addresses match the ones that will subsequently appear in your exception, and get more information about the problem. Or, you can even print descriptions using the hex addresses directly: po 0xa469e50 for example (may have to typecast it, though).

Other than that, you haven't really provided enough code for someone to just look at it and say what the problem is :) But the above should help you work it out.



回答2:

Rather than replacing the popoverContent's view, could you add the listTable as a subview?

Not sure if that would fully accomplish what you're looking for but it might avoid the hierarchy inconsistency error.