发布于 

Interface Builde(nib和xib的深究)

iOS开发肯定熟悉xib和nib。以下是我收拾出来的资料。

xibnib都是Interface Builder的图形界面设计文档。


nib和xib的历史

nib这个名字来自于NeXTSTEP系统,在NeXTSTEPApple收购之前,一直使用nib作为Interface Builder的图形文档,nib的发展经过了nib2.0nib3.0,到NeXTSTEPApple收购之后,带有NeXTSTEP标志的nib被换成了xib


nib和xib的异同

xib是一个XML格式的纯文本文件,nib是一个二进制文件。xib比nib有一个很明显的优势。

可以进行diff操作。

不管是xib还是nib,Xcode编译后都将得到一个供程序运行时使用的经过编译的二进制nib文件。现在最新版本的Xcode在创建项目时,已经默认使用xib格式的文档了。

我这里简单的说一下diff算法,就是即给定任意两棵树,找到最少的转换步骤。为什么又扯到了树呢,熟悉XML的可能知道,XML 文档形成了一种树结构,它从“根部”开始,然后扩展到“枝叶”。xib中可以认为,每一个节点是一个UI控价,diff算法可以高速的找到两颗树的区别,就是说可以高速的找到两个界面的区别,然后对两个界面进行部分的刷新就可以转换了。(React的虚拟DOM技术也用到了这个思想)想知道更多可以去百度或Google diff算法。


nib和xib编译生成二进制nib文件过程

IB所用的文档的序列化,序列化的结果就是这个XML文件。它保存的是所有界面的资源信息和各个对象之间的关系。编译时对这个xml文件进行的序列化,序列化的结果是二进制的nib文件。

编译时对xml文件做了如下操作:

        1.  读取xml文件,生成所有界面对象,生成所有object(即自定义的controller类等),设置好各个obejct之间的联系(IBActionIBOutlet

        2.  对这一坨对象进行序列化,即调用encodeWithCoder方法来序列化,生成二进制nib文件为什么要生成二进制文件,因为从二进制文件生成类实例更快一些。

而在程序运行时,对nib文件进行反序列化的过程

 运行时对nib的操作 :

        1.  反序列化,调用所有对象的initWithCoder方法
2.  某些类的initWithFrameinit之类的方法被调用,生成所有类实例

        3.  发送awakeFromNib消息,每个类实例的awakeFromNib被调用


引用《Cocoa Programming for Mac OSX》一书的说法,Interface Builder 把窗口、菜单栏以及窗口上的各种控件的对象都“冻结”在了一个 NIB文档里面了;程序运行时,这些对象将会“苏醒”。

        猜测nib2.0/3.0时代的多出来的二进制文件应该就是被编译序列化之后的文件,即nib2.0/3.0nib文件由界面信息文件和运行时二进制文件组成。
由以上的可以看出,凡是被拖到nib里面的对象都会被自动创建实例,无需你代码手动创建(扫盲了。。。),需要用到的话,添加一个IBOutlet即可。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @shyiuanchen 创建,使用 Stellar 作为主题。