UIViewController的基础功能是管理界面中的view,但是一个复杂的应用程序肯定有好多的视图控制器,那么自然如果视图控制要有管理自己的功能就更加强大。先看API文档:Viewcontrollersrarelyoperateinisolation.
Ifyourapplicationusesanavigationortabbarcontroller,
orifyourapplicationpresentsviewsmodally,
thenittypicallyhasseveralviewcontrollers
interactingwitheachothertoimplementthosenavigationfeatures(视图控制器很少单独使用。假如你的应用程序要使用导航或者转换条控制器,或许是你的应用程序要呈现模态的视图,明显的这里有很多的视图控制器相互关联来实现导航的功能)。所以可以看出,UINavigationController和UITabBarController是用来控制视图控制器的使用的,同样他们的跟视图也是UIViewController,这里就说明了UIViewController是自己可以控制自己的。这也是为何我们使用UINavigationController的时候不允许在把一个NavigationController推入堆栈中,这样极容易形成自己队递归调用自己,造成堆栈溢出。以下是使用UIViewController应该注意的地方。
1.首先看loadView和viewDidLoad的区别,两者都是用来初始化试图控制器中的视图如何显示的。还是先看官方API解释:Ifyoucreateyourviewsmanually,youmustoverridethismethodanduseittocreateyourviews.
Ifyouuse Interface Buildertocreateyourviewsandinitializetheview controller thatis,
youinitializetheviewusingtheinitWithNibName:bundle:method,
setthenibNameandnibBundlepropertiesdirectly,orcreatebothyourviews
andviewcontrollerinInterfaceBuilder—thenyoumustnotoverridethismethod.(如果你手动创建一个视图控制器,你必须重载这个方法,去使用他创建你的视图。如果你使用Interfacebuilder创建和初始化的视图控制器,你就不必重载此方法)。所以当你手动创建一个视图控制器的时候一定要注意重载loadView,否则你的视图将不回显示你增加的任何字视图。
2.viewDidUnLoad这个方法最容易误导人,先看API解释:Calledwhenthecontroller’sviewisreleasedfrommemory(当控制器的视图从内存中释放的时候被调用),个人觉得官方的解释对英语非母语的国家的人来说,很容易理解为视图控制器release的时候,调用此方法。但是如果实际调试以下,视图控制器释放的时候不会调用该方法。再进一步分析API文档:ThismethodiscalledasacounterparttotheviewDidLoadmethod.
Itiscalledduring low memoryconditionswhentheviewcontrollerneedstoreleaseitsview
andanyobjectsassociatedwiththatviewtofreeupmemory(这个方法是被调用相对于viewDidLoad方法的,在内存警告的情况下,当试图控制器需要释放它的视图和这个视图中相关联的任何对象来释放内存的时候,调用此方法)。这里还有一点要注意的时,当出现内存警告的时候,是调用正在显示的视图控制器的父视图控制器的viewdidUnload方法,而不是正在显示的视图控制器的viewDidUnload方法。因为如果调用了正在显示的视图控制器的viewDidUnload方法,那么用户正在看的界面就会消失,虽然释放了内存但是用户显然没法接受,自然要释放该视图下面看不到的视图控制器中的视图。被释放的视图,下次加载的时候再调用viewDidLoad的方法,所以ViewDidUnload的方法是和viewDidload方法相互对应的。
3.为了方便内存的管理,曾经写过这样的代码:
MyNibController *nibController = [[myNibController alloc] initWithNibName:@"myNibController" bundle:nil]; [self.view addSubview:nibController.view]; [nibController release];
分析下这样的代码潜在的危害,这个应该清楚一点当AddSubView这个方法调用的时候,nibController.view这个视图的引用计数就会加1。但是这里释放了nibController这个控制器,那么管理这个视图的控制器没有了,但是该视图确实还存在。想象下,就像你开动了汽车发动机,但是没有人驾驶,任之随便的跑,这辆汽车会带来多大的危害。这里很容易出问题的地方就是,如果再nibController中写了一个按钮响应方法:(-IBAction)click(id)sender,当点击此按钮的时候程序就会crash掉,因为这个方法已经不存在了,自然会badaccess。
4.有时候常常需要找到一个view的控制器。怎么办,其实从官方API中也是可以找到的。API解释:UIViewControllerispartofyourapplication’scontrollerlayer,
aviewcontrollerisresponsibleforcoordinatinginteractionsbetweenyourapplication’svisualpresentation(yourcustomviews)
andyourapplication’sdatamodel(yourcustomobjects).
Aviewcontrollerisalsoresponsibleforhandlingchangestotheviewsthatcompriseitsviewlayer.(视图控制器是应用的控制器层的一部分,一个视图控制器视图层和数据层交互时的响应者,一个视图控制器也能响应视图层中的响应控制)这个自然就找到方法如下,这个假如view是当前的视图:
UIResponder* nextResponder = [view nextResponder]; if ([nextResponder isKindOfClass:[UIViewController class]]) { return (UIViewController*)nextResponder; }