UIViewControllerHierarchyInconsistencyException异常

本文探讨了iOS中MVC模式的应用,详细介绍了UIViewController和UIView的关系。解释了UIViewControllerHierarchyInconsistency异常的原因,并给出了避免此类异常的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IOS中的MVC  

      MVC模式是一种经典的软件架构模式,基本上懂程序设计的人都了解或应用过MVC模式。多数面向对象的程序设计架构都得益于MVC模式来有效的划分程序中的对象的角色,组织对象之间的耦合关系(MVC的具体定义和描述可以参见  维基百科 ),Cocoa Touch提供了IOS的开发环境,包含了诸多基础类库和框架,其中UIKit框架提供并实现了MVC模式。在IOS中UIViewController表示控制器,UIView代表视图。每一个UIViewController对象中都拥有一个view属性用以管理一组UIView对象。做过IOS开发的人都知道,一个Application的记载过程都伴随着两个对象树结构的生成,一个是控制器树形结构,另一个是视图树形结构,在UIViewController的viewDidLoad方法中,我们可以创建多个子控制器,并将子控制器下的view对象添加至父控制器的view对象中,这样依次迭代最终会完成两个对象树的创建。如图 
                                         
 
      其实,做过前端开发的人都看的出来,图中的controller的树结构和view的树结构,单独拿出一个来都和DOM的树结构类似,都是父与子,兄弟与兄弟之间的关系。 

异常的出现  

      前面简单的描述了一下controller树和view树,其实这里面是有一点规定的,即:controller的树节点必须与view的树节点在层次结构上保持一致。这里所谓的一致是指一个subController所管理的view必须是其父控制器superViewController所管理view的子view 。这个一致性的规定好像在IOS的开发文档中并没有着重说明,可能是本人自己还未看到。因之前在项目中不小心违背了这个规定,因此得到一下错误: 

1 Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency',
2 reason: 'child view controller:<ViewControllerC: 0x6a3b7c0> should have parent view controller:<ViewControllerB: 0x6a46990> but actual parent is:<ViewControllerA: 0x6a49f70>'

      错误的说明很简单。所以循着错误的提示,就在IOS文档中搜索了一下UIViewControllerHierarchyInconsistency异常,发现该异常就在UIViewController类文档的最下方。 
其释义大致如下: 
因控制器的层次与视图的层次不一致会引发该异常。 当视图控制器的视图添加到视图层中,系统会遍历视图层来找到其第一个拥有视图控制器的父视图。找到的该父视图的视图控制器也必须是刚添加的 视图的所对应视图控制器的父控制器。否则会抛出该异常。当视图控制器通过addChildViewController方法被添加进来后,也会进行之前的一致性监测。 不存在父试图控制器的视图控制器,也可以将其视图添加到视图层中。但通常极少数情况下才会用到这种方式。

      源文档直译过来有些拗口建议大家参考下 源文档释义。 



 

ios error:A view can only be associated with at most one view controller at a time

xcode 4.3.2上的工程运行,没有问题,更新到xcode4.5.1后,运行,提示异常:

Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View < UIView: 0xa192d00; frame = (0 20; 320 460); autoresize = W+H; layer = < CALayer: 0xa192d60>> is associated with < UIViewController: 0xa195c70>. Clear this association before associating this view with < CustomViewController: 0xa1802a0>.'


google了半天,找到解决方案:

说明一下:1.将之前view controller之下的view,从view controller中移出,直接拖拽就可实现

                  2.然后将view controller删除。在file's owner ,class设置你你自己的class(红框处)


问题是解决了,但是原因还是没找到,有知道的朋友留个印。。。



UIViewControllerHierarchyInconsistency试图提出一个模态视图控制器时

MapViewController *mapView = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
 mapView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
 [self.navigationController presentModalViewController:mapView animated:YES];
 [mapView release];

不断收到以下错误..
'UIViewControllerHierarchyInconsistency', reason: 'A view can only be associated with at most one view controller at a time! View <UIView: 0x1ed815a0; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x1ed81600>> is associated with <UIViewController: 0x1ed835a0>. Clear this association before associating this view with <MapViewController: 0x1dd947c0>.'

你应该像这样做..

MapViewController *mapView = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
UINavigationController *navCntrlr = [[UINavigationController alloc] initWithRootViewController:mapView];
mapView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
//hide navigation bar if needed
[self.navigationController presentModalViewController:navCntrlr animated:YES];
[mapView release];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值