一个ViewController,一般通过init或initWithNibName来加载。二者没有什么不同,init最终还是要调用initWithNibName方法(除非这个ViewController没有nib文件)。

我们经常在initWithNibName方法中初始化视图,变量或者其他成员。这是最常见的initWithNibName方法写法:

- (id)initWithNibName:(NSString *)nibNameOrNilbundle:(NSBundle *)nibBundleOrNil

{

self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

label=[[UILabelalloc]initWithFrame:

CGRectMake(0,0,160,160)];

[self.viewaddSubview:label];

...

}

returnself;

}

在if语句中,包含了最常见的成员初始化代码。

在这段代码中,如果你向ViewController的视图树中加入一些新的UIView子类,比如上面的代码:

[self.viewaddSubview:label];

这不会有什么问题。但是这会导致另一个方法的调用,即viewDidLoad方法。

viewDidLoad方法一般情况下只会在nib文件已载入内存(即视图树构建完成)之后调用。

但还有另一种情况,如果ViewController的view属性被引用时,view=nil,也会导致nib的加载行为,从而也导致viewDidLoad方法的调用。如果你在initWithNibName方法一直不引用view属性,则直至initWithNibName方法结束,viewDidLoad方法也不会触发。

你也许奇怪,如果在代码中你一直不引用这个ViewController的view属性怎么办?那么是不是viewDidLoad方法一直都不会调用了?

它会在ViewController对象第1次present时调用,比如你使用presentModalViewController或pushViewController方法弹出它。这两个方法同时还会调用ViewController的appear方法(即viewWillAppear方法和viewDidAppear方法)。

viewDidLoad方法会比appear方法要早执行(appear方法会导致一个弹出动画产生)。而且如果在present之前已经执行过viewDidLoad方法,则present方法不会触发viewDidLoad方法。

这就是为什么我们会奇怪viewDidLoad方法中的代码有时执行有时似乎不被执行的原因。其实根源还是在initWithNibName方法的if语句中。

如果你在initWithNibName时,引用了ViewController的view属性,由于此时view为nil,将触发nib文件的加载行为,导致viewDidLoad方法不等present就提前调用了。由于initWithNibName方法中ViewController成员还未初始化,导致任何对这些成员的引用都是无效的。

比如在viewDidLoad方法中,由于该方法提前执行,导致数据访问对象还是nil(initWithNibName仍然未执行完)。如果此时在viewDidLoad方法想通过数据访问对象获取表格数据,将得到空。这样从表面上看,viewDidLoad方法似乎未被执行。

这个情况可以通过两种方法来改进:

一、initWithNibName方法中,不要有任何成员初始化的代码。把这些代码移到viewDidLoad方法开始进行。

二、由于initWithNibName方法保证是在present方法中进行,我们也可以在initWithNibName方法中保留成员初始化代码。但把原来viewDidLoad方法中的代码移到appear方法中。也就是,最好不要在viewDidLoad方法中进行和成员初始化无关的事情。这样还有一个好处,每次presentViewController,都会执行appear方法中的代码(如果是viewDidLoad方法,则只会在加载nib时执行)。

loadview也是第1次引用ViewController的view属性(此时,view=nil)时调用,但在viewDidLoad之前。不同的是,loadview在view树构建前调用,viewDidLoad在view树构建完成后调用。二者之间,则进行nib的加载。因此,我们常在编程方式创建viewcontroller时重载loadview方法,因为本来就不需要加载nib的内容。

 
0

浅论ViewController的加载 -- 解决 viewDidLoad 被提前加载的问题(pushViewController 前执行)的更多相关文章

  1. [转]浅论ViewController的加载 -- 解决 viewDidLoad 被提前加载的问题(pushViewController 前执行)

    一个ViewController,一般通过init或initWithNibName来加载.二者没有什么不同,init最终还是要调用initWithNibName方法(除非这个ViewControlle ...

  2. iOS 解决LaunchScreen中图片加载黑屏问题

    iOS 解决LaunchScreen中图片加载黑屏问题 原文: http://blog.csdn.net/chengkaizone/article/details/50478045 iOS 解决Lau ...

  3. netload 加载程序集抛异常----无法加载程序集解决办法

    netload 加载程序集抛异常----无法加载程序集 错误信息如下: 无法加载程序集.错误详细信息: System.BadImageFormatException: 未能加载文件或程序集“file: ...

  4. [Android Pro] so 动态加载—解决sdk过大问题

    原文地址: https://blog.csdn.net/Rong_L/article/details/75212472 前言 相信Android 开发中大家或多或少都会集成一些第三方sdk, 而其中难 ...

  5. 使用Redirector插件解决googleapis公共库加载的问题【转】

    转自:http://www.cnblogs.com/kari/p/5860371.html 最近访问一些面向国外的网站总是会出现ajax.googleaips.com无法加载的情况.以下为加载stac ...

  6. 使用Redirector插件解决googleapis公共库加载的问题

    最近访问一些面向国外的网站总是会出现ajax.googleaips.com无法加载的情况.以下为加载stackoverflow时的情境: 图1 -无法加载的google公共库 问题的原因是谷歌没有在国 ...

  7. 过滤器解决hibernate中懒加载问题

    使用过滤器解决懒加载问题需要我们对过滤器的生命周期有深刻的理解 1.浏览器发送一个请求 2.请求通过过滤器执行dofilter之前的代码 3.浏览器通过过滤器到达Servlet(注意我们这里的serv ...

  8. 解决 Visual Studio 符号加载不完全问题

    解决 Visual Studio 符号加载不完全问题 工具 - 选项 - 搜索 "符号" - 选上服务器 | 加载所有符号, 之后符号就会显示完全

  9. 解决页面初始化vue加载代码问题

    <style type="text/css"> /* 解决页面初始化vue加载代码问题 */ [v-cloak] { display: none; } </sty ...

随机推荐

  1. Wince 6.0适用 .NET 使用HttpRequest的Post上传文件,服务端的Web API接收Post上传上来的文件 代码

    //调用的示例 private string fileName = "InStorageData.csv"; string filePath = parentPath + Comm ...

  2. LINUX退出当前进程——比较return、exit()

    1.在Linux中任何让一个进程退出 进程退出表示进程即将结束.在Linux中进程退出分为了正常退出和异常退出两种. 1>正常退出 a. 在main()函数中执行return . b.调用exi ...

  3. 【转】NVelocity模板引擎初学总结

    转自:http://sunxitao88.blog.163.com/blog/static/68314439200861963326251/ 前不久,接触到.NET下的MVC-MonoRail,它推荐 ...

  4. Linux课程实践二:编译模块实现内核数据操控

    一.内核模块原理 1. Linux内核增加功能 Linux内核整体结构很庞大,包含了很多的组件,现在有两种方法将需要的功能包含进内核当中: - 静态加载:将所有的功能都编译进Linux内核. - 动态 ...

  5. 用node搭建静态文件服务器

    占个坑,写个node静态文件服务器

  6. bootstrap datetimerange

    天用的了bootstrap日期插件感觉搜索的资料不是很多在此写下一些使用的心得: 插件开源地址:daterangepicker日期控件, 插件使用只要按照开源中的文档信息来就好先包括以下引用: < ...

  7. cookie以及cookie的作用

    ios中对cookie操作的两个类分别是:1. NSHTTPCookie  2. NSHTTPCookieStorage,具体的使用在这里就不多说了. 1.什么是Cookie("小甜饼&qu ...

  8. The remote name could not be resolved问题的解决方法

    网站如果绑定了代理ip,内部跳转的时候,就会报The remote name could not be resolved错误,这个错误很难排查,网上也没有多少可参考的例子 现在记录下解决方法,以备参考 ...

  9. python中的告警处理

    在Python中,遇到异常时,一类是直接抛出异常,exception:另一类直接告警warning. 对于后者,通常是打印一句话.前者则或中断程序执行. 考虑到避免由于告警导致后续的不可预知的错误,可 ...

  10. PagedDataSource、Repeater以及AspNetPager在ASP.NET上分页。

    一.前台使用服务器标签 1.1使用Repeater控件 <asp:Repeater ID="Repeater1" runat="server"> & ...