iOS Storyboards / NIB低级解剖。 他们如何实施?

我对iOS中的NIB / Storyboards机制的低级细节感兴趣。 我想了解更多关于他们的实现 – 我有兴趣开发我自己的机制。 我在Apple网站上find了关于NIB文件的一些信息。

他们说: a nib file describes these objects exactly as they were configured in Xcode. At runtime, these descriptions are used to recreate the objects and their configuration inside your application. a nib file describes these objects exactly as they were configured in Xcode. At runtime, these descriptions are used to recreate the objects and their configuration inside your application. 。 好。 但是我找不到有关故事板如何实现的信息。 故事板是一堆(包)的NIB文件 – 每个UIViewController ? 或者它使用不同的机制?

那么NIBs / Storyboard的XML来源呢? 是否有一些从XML到Objective-C源代码的发泄翻译? 低层次的细节将不胜感激。

Storyboard和XIB文件被编译成二进制格式的NIB文件。 这些文件是您在部署应用程序时可以在软件包中find的文件。

NIB文件更容易理解。 它们包含一个对象层次结构的数组。 故事板更复杂,因为它们包含整个场景,所以还包含更多的元数据(例如,哪个视图控制器是场景中的初始等)。 分段也是可解码的对象。

在NIB文件和故事板中定义的每个对象都有一个唯一的键值(例如vXZ-lx-hvc ,编译后的名称附加了该类的名称,所以最后是LNViewController-vXZ-lx-hvc )。

当您尝试加载在NIB或故事板中定义的对象(通常是视图,视图控制器和segues,以及可以在Interface Builder中定义的其他对象)时,将创build一个types为UINibDecoder的解码器,该解码器负责读取二进制NIB文件并将其解码为活动对象。 然后分配一个对象并调用initWithCoder:来传递解码器。 然后该对象为其支持的每个属性调用各种解码方法。 例如,表格视图可以解码其样式,背景视图,单元格高度,委托等等。解码完成后,NIB加载器调用awakeFromNib来通知从NIB加载的对象。

故事板被编译成多个NIB文件,通常是每个视图控制器的NIB文件。 当从故事板加载对象时,内部UIStoryboard具有用于为特定视图控制器加载NIB文件的元数据。 当视图控制器被解码时(在它的initWithCoder: ,它加载它的整个视图层次结构,属性值,附加对象等

最后,每个NIB文件(以及扩展的故事板)都能够包含键值信息,这些信息在对象被成功解码之后应用。

要实现一个类似的系统,你需要提供一个类似的系统,可以推导出一个types,分配一个对象,然后用你自己的解码器初始化它。 由于视图和视图控制器实现NSCoding协议,您可以轻松调查他们支持的密钥,并创build解码器和数据格式以支持相同的密钥。


如果您希望遵循NIB和故事板加载stream程,我build议查看类转储,为关键方法设置断点并检查传递给方法调用的参数。 在64位模拟器上进行debugging时,程序集输出非常容易阅读,并且可以使用po $arg1作为self对象,使用po NSStringFromSelector($arg2)调用方法select器po $arg3 ,从而轻松检查传递的参数。 ..以下参数。

build议的方法开始于:

 -[UIStoryboard instantiateViewControllerWithIdentifier:] -[UIStoryboard instantiateInitialViewController] -[UIStoryboard nibForViewControllerWithIdentifier:] -[UINibDecoder decodeObjectForKey:] 

(和另一个 – -decode***ForKey:方法)

设置符号断点并查看传递的程序集和参数。


使用状态恢复时会发生非常类似的过程。 不同之处在于,视图提供了一个编码器,并将它们的属性编码给编码器; 在恢复期间,视图从状态恢复解码器恢复。

在一个非常高的层次上(为了详细描述大量的实现细节),Xcode使用Cocoa的本地对象持久化机制(称为NSCoding)序列化您创build的对象图(视图层次结构等)。

NSCoding是一种协议,它允许任何符合它的对象的graphics被序列化并保存到磁盘或通过networking传输,然后被重构回到原始对象图中。

当然,像sockets和动作这样的东西也必须存储,所以比起顶层对象和一堆视图还要多一些,但是你可以把xib文件看作是视图层次结构的XML序列化在Xcode中构造。