iOS initWithFrame、initWithCoder、awakeFromNib的区别解析

首先区别:

initWithFrame::使用代码(纯代码创建)加载生成对象的时候调用

initWithCoder::使用文件(xib或者storyBoard)加载的对象时调用

其次区别:

initWithCoder::从xib或者storyBoard加载完毕才会调用

awakeFromNib:只要对象从文件解析来的就会调用

同时存在的时候,会先调用initWithCoder:方法,initWithCoder:方法创建控件, awakeFromNib将控件激活唤醒

awakeFromNib:是从nib文件中唤醒对象,完成对每一个对象的实例化或与nib文件的关联。[NSBundle loadNibFile:externalNameTable:withZone:],加载nib文件,完成初始化设置和连接,并且在所有关联的对象上唤醒awakeFromNib方法。

说一下Nib对象的生命周期:
- 当nib文件加载到内存中时,nib加载代码需要几个步骤来确保nib文件中的对象被正确的创建和初始化。
1、将nib文件和任何引用资源文件的内容加载到内存中,但未解档。
2、解档nib对象数据并实例话对象。如何实例话对象取决于对象的类型以及其在归档中的编码方式。nib加载代码使用一下顺序来确定要使用的初始化方法。
  - 默认情况,对象收到一个`initWithCoder:` 消息。在iOS中,使用initWithCoder:方法初始化符合NSCoding协议的任何对象。这其中包括UIView和UIViewController的所有子类,无论它们时默认的XCode库或定义的自定义类的一部分。
  - OS X 中自定义的视图会收到一条 `initWithFrame:`消息。
  - IOS中的自定义视图不会使用 `initWithFrame:`方法初始化。
  - 除此之外,自定义对象接收`init`初始消息。

3、重新建立nib文件中对象之间的所有连接(action、 outlet和绑定)。这包括与File‘s和其他占位符对象的连接。建立连接的方法因平台而异:
  - outlet连接,在iOS中,nib加载代码使用`setValue:forKey:`方法连接每个outlet。该方法同样寻找适当的访问器方法,并且在失败时使用其他方式。在 iOS 中设置 outlet 还会为任何注册的观察者生成 KVO 通知。这些通知可能在所有对象间连接重新建立之前发生,并且在调用任何对象的` awakeFromNib `方法之前肯定会发生这些通知。
  - 动作连接,nib加载代码使用UIControl对象的`addTarget:action:forControlEvents:`方法来配置操作,如果目标为空,则动作由响应链处理。
  - 绑定,在OS X中,Cocoa 使用源对象的 `bind:toObject:withKeyPath:options:` 方法来创建它与其目标对象之间的连接。iOS中不支持绑定。

4、将一个`awakeFromNib`消息发送到nib文件中定义匹配选择器的相应对象:
  - 在 OS X 中,该消息被发送到定义该方法的任何界面对象。它也被发送到 File's Owner 和定义的任何占位符对象。
  - 在iOS中,此消息仅发送到由nib加载代码实例化的界面对象,他发送不到File's Owner、第一响应者或任何其他占位符对象。

5、显示在nib文件中启用了“Visible at launch time”属性的任何窗口。

Nib文件中对象的生命周期
每次NSboundle或者NSNib类加载nib文件时,底层代码会创建该文件中的对象的新的副本并将其返回。你需要确保在必要的时候持有新的对象,并在完成之后取消。通常我们需要对最上层的对象强引用确保它们不会被释放。你不需要强引用对象图中比较基层的对象,因为它由它们的父母节点拥有,你应尽量减少循环引用的风险。
iOS的outlet应该被定义为声明的属性,outlets应该是weak的,除了nib文件对应的File‘s Owner和nib文件拥有的顶级对象应该是强引用创建的outLet 应该是weak的。(Xib创建控件时已经和代码形成引用关系,Xib中的对象就需要我们弱引用weak)。

每当加载nib文件时,都应该始终制定一个对象作为该nib文件的File‘s Owner,它是运行代码和即将在内存中创建的新对象之间的主要接口。所有的nib加载方法提供了一种方法来直接指定 Files‘ Owner,或者作为选项字典中的参数。
nib文件加载过程中涉及从磁盘中读取nib文件,然后实例化其包含的对象,然而使用UINib和NSNib类,从磁盘中读取nib文件只要一次,并将内容存储在内存中,因为它们在内存中,创建连续的对象集需要更少的时间,不需要访问磁盘。
使用UINib和NSNib 类的两步: 首先,创建一个类的实例,并使用nib文件的位置信息进行初始化。其次,将实例化的内容以将对象加载到内存中,每次实例化nib文件时,都需要指定一个不同的Files‘ Owner对象并接收一组新的顶级对象。

nib结构加载的时候,发送一个awakeFromNib消息告诉每个对象重建一个nib归档,当只有在所有的档案中的对象已记载和初始化,当一个对象加收awakeFromNibmessage,这是保证其所有出口和行动链接已建立。
符合NSCoding协议的对象使用initWithCoder:方法初始化,不符合NSCoding协议所有的对象使用init方法初始化,在所有的对象被实例化和初始化,nib加载代码,将所有的这些对象的出口和动作的连接,之后调用对象的awakeFromNib方法。
Nib文件是程序中所有对象的存档。程序启动,对象从文件中被解档,赋予新的使命,等待用户的触发。

原文地址:https://www.cnblogs.com/Free-Thinker/p/12749962.html