initWithNibName,awakeFromNib和viewDidLoad的描述?

是否有一个很好的概述initWithNibNameawakeFromNib ,和viewDidLoad ,列出了使用每一个这些最好的方法,并准确地描述每个做什么? 我觉得这些很混乱 在使用View Controller生成的模板中,有关initWithNibName的注释说:

指定的初始化程序。 覆盖以执行视图加载之前所需的设置。

除了这个方法似乎永远不会被调用(我使用IB来设置视图控制器)。 那么我应该使用awakeFromNib还是viewDidLoad来初始化呢?

如果您在IB中创build视图,则应该使用viewDidLoad 。 每当视图初始化时都会调用它。 你使用initWithNibName :当你在代码中创build你的视图。 你不应该使用awakeFromNib和iPhone的视图。

initWithNibName看起来不被调用的原因是界面构build器实际上创build了一个视图控制器的实例,然后序列化该视图。 所以,当你在IB中创build视图控制器(基本上把它添加到你的项目中)时,IB调用initWithNibName ,但是除非你已经重写了默认的encodeWithCoder那么你在视图中设置的任何瞬态variables从笔尖加载(反序列化)。 这通常是可以的,因为你通常想用你的应用程序的当前信息,运行上下文而不是预定的初始化程序来设置你的视图。

即使你是以编程方式创build视图和视图控制器,但是,你仍然可以把所有的初始化放在viewDidLoad 。 这往往是更好的,因为如果你的视图最终获得caching(卸载),然后带回到屏幕上, viewDidLoad可以再次调用,而初始化不一定是。 例如,以编程方式创build一个视图并将其推送到导航控制器的堆栈上 – 稍后视图被遮盖,并发出内存警告,以便导航控制器“卸载”视图但不释放对象 – 视图(其他视图会popup),导航控制器将再次调用viewDidLoad ,以便重新初始化,但initWithNib不会再被调用。 请注意,这是一个罕见的情况,然而,无论如何,大多数人的应用程序会因为其他原因而死亡。

我刚刚完成了关于这个话题的一些研究,所以我想我会分享一些我学到的东西。

  1. 使用awakeFromNib和iPhone的视图没有任何问题。 请参阅此Apple Dev文档 。

  2. 当视图从NIB文件加载时initWithCoder 不是一个很好的初始化的地方,因为同一个NIB文件中的其他项目可能已经或可能没有被初始化。 因此,例如,销路可能仍然是零。 当调用awakeFromNib时,保证在相同的NIB文件中的所有项目都被正确初始化。

  3. viewDidLoad 在viewController中进行设置工作的好地方。

那么为什么要在视图中使用awakeFromNib呢? 我能想到的一个原因是,如果在视图初始化并且连接到NIB文件中的其他对象之后,您想要做的事情,但是只想将其封装在视图中。 这减less了与视图控制器的连接。

viewDidLoad可以被多次调用,所以对于大多数初始化来说这不是一个合适的地方(尽pipe实际上它只被调用一次,除非你插手) – 这就是为什么awakeFromNib是特殊的和非常必要的:它只被调用一次。

viewDidLoad不存在UIView – UIView有awakeFromNib初始化,没有其他合理的select。

在过去的六个月中,我一直很高兴地使用awakeFromNib与故事板(一个应用程序的单一故事板),没有任何麻烦,它已经完美configuration文档中指定的所有sockets的行为。 然后今天我分开了一些代码,并把一个新的视图控制器和视图,没有任何工作,因为我曾经经历过,即所有网点零在awakeFromNib。 我的理论很简单 – SDK很糟糕,因为在你的控制器/视图和类链中的某个地方做一些微不足道的事情是很容易的,并且破坏了一切。

现在我正在研究这个毫无意义的话题,但是当我需要的只是一个简单的一致的地方来做初始化。