问题
I became interested in low-level details of NIB/Storyboards mechanisms in iOS. I want to learn more about their implentation - I'm interested in developing of my own mechanism. I found some information about NIB files on the Apple site.
They said: 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.
. Ok. But I couldn't find any information on how storyboards implemented. Does storyboard is just a bunch (pack) of NIB
files - one for each UIViewController
? Or it use a different mechanism?
And what about the XML
source of NIBs/Storyboards? Are there some underhood translator from XML to Objective-C source code? Low level details will be appreciated.
回答1:
Storyboard and XIB files are compiled into binary-format NIB files. These files are what can be found in the bundle when you deploy your application.
NIB files are simpler to understand. They contain an array of object hierarchies. Storyboards are more complex, as they contain an entire scene, so there is more metadata included (such as which view controller is the initial in the scene, etc.). Segues are also decodable objects.
Each object defined in NIB files and storyboards have a unique key (such as vXZ-lx-hvc
, which when compiled, have the name of the class appended to it, so it is finally LNViewController-vXZ-lx-hvc
for example).
When you attempt to load objects defined in a NIB or a storyboard (usually views, view controllers and segues, but also other objects you can define in Interface Builder), a decoder of type UINibDecoder is created, which is responsible for reading data in the binary NIB file and decoding it into live objects. Then an object is allocated and initWithCoder:
is called, passing the decoder. The object then calls the various decode methods for each property it supports. For instance, a table view would decode, among other things, its style, its background view, its cell height, its delegate, etc. After decoding is complete, the NIB loader calls awakeFromNib
to notify the object it has been loaded from a NIB.
Storyboards are compiled into multiple NIB files, usually a NIB file per view controller. When objects are loaded from a storyboard, internally UIStoryboard
has metadata for which NIB file to load for the particular view controller. When the view controller is being decoded (within its initWithCoder:
, it loads its entire view hierarchy, property values, attached objects, etc.
Finally, each NIB file (and, by extension, storyboards) is capable of including key-value information, which is applied after the object has been successfully decoded.
To implement a similar system of your own, you would need to provide a similar system that can deduce a type, allocate an object, and then initialize it with your own decoder. Since views and view controllers implement the NSCoding
protocol, you could investigate easily what keys they support and create your decoder and data format to support the same keys.
If you wish to follow the NIB and storyboard loading flows, I suggest looking at the class dumps, setting breakpoints for key methods and inspecting passed parameters to method calls. When debugging on the 64-bit simulator, the assembly output is very easy to read, and you can inspect passed parameters easily using po $arg1
for the self
object, po NSStringFromSelector($arg2)
for the called method selector, po $arg3
... for following parameters.
Suggested methods to start with:
-[UIStoryboard instantiateViewControllerWithIdentifier:]
-[UIStoryboard instantiateInitialViewController]
-[UIStoryboard nibForViewControllerWithIdentifier:]
-[UINibDecoder decodeObjectForKey:]
(and the other -decode***ForKey:
methods)
Set a symbolic breakpoint and look at the assembly and parameters passed.
A very similar process takes place when using state restoration. The difference is, views are provided a coder and they encode their properties to that coder; during restoration, views are restored from the state restoration decoder.
回答2:
At a very high level (to gloss over a ton of implementation details), Xcode serializes the object graph that you created (the view hierarchy, etc.) using Cocoa's native object persistence mechanism, known as NSCoding.
NSCoding is a protocol that allows any graph of objects that conform to it to be serialized and saved to disk or transmitted over a network, and then be reconstructed back into the original object graph.
Of course things like outlets and actions also have to be stored, so there's a bit more to it than just the top-level objects and a bunch of views, but you can think of a xib file as an XML serialization of the view hierarchy you construct in Xcode.
来源:https://stackoverflow.com/questions/22533418/ios-storyboards-nibs-low-level-anatomy-how-are-they-implemented