NIB 和 XIB 的區別與聯系
NIB 和 XIB 都是 Interface Builder 的圖形界面設計文檔。引用《Cocoa Programming for Mac OSX》一書的說法,Interface Builder 把窗口、菜單欄以及窗口上的各種控件的對象都“凍結”在了一個 NIB文檔里面了;程序運行時,這些對象將會“蘇醒”。
在終端下我們可以看到,NIB 其實是一個目錄。它里面有兩個也是后綴為 NIB 的文件:designable.nib 和 keyedobjects.nib。前者是一個 XML 文檔,而后者則是一個二進制文件。Interface Builder 3 之后,引入了新的文檔格式:XIB。它是單一的 XML 文檔,也就是一個純文本文件。純文本文件的好處是顯而易見的。嗯,就是便於源代碼版本管理。現在最新版本的 Xcode 在創建項目時,已經默認使用 XIB 格式的文檔了。
不論在 Interface Builder 中選擇的是 NIB 還是 XIB 格式,Xcode 編譯后都將得到一個供程序運行時使用的經過編譯的 NIB 文件。
NIB的生命周期
1.It loads the contents of the nib file and any referenced resource files into memory:
The raw data for the entire nib object graph is loaded into memory but is not unarchived.
Any custom image resources associated with the nib file are loaded and added to the Cocoa image cache; see “About Image and Sound Resources.”
Any custom sound resources associated with the nib file are loaded and added to the Cocoa sound cache; see “About Image and Sound Resources.”
2.It unarchives the nib object graph data and instantiates the objects. How it initializes each new object depends on the type of the object and how it was encoded in the archive. The nib-loading code uses the following rules (in order) to determine which initialization method to use.
a. By default, objects receive an initWithCoder: message.
In OS X, the list of standard objects includes the views, cells, menus, and view controllers that are provided by the system and available in the default Xcode library. It also includes any third-party objects that were added to the library using a custom plug-in. Even if you change the class of such an object, Xcode encodes the standard object into the nib file and then tells the archiver to swap in your custom class when the object is unarchived.
In iOS, any object that conforms to the NSCoding protocol is initialized using the initWithCoder: method. This includes all subclasses of UIView and UIViewController whether they are part of the default Xcode library or custom classes you define.
b. Custom views in OS X receive an initWithFrame: message.
Custom views are subclasses of NSView for which Xcode does not have an available implementation. Typically, these are views that you define in your application and use to provide custom visual content. Custom views do not include standard system views (like NSSlider) that are part of the default library or part of an integrated third-party plug-in.
When it encounters a custom view, Xcode encodes a special NSCustomView object into your nib file. The custom view object includes the information it needs to build the real view subclass you specified. At load time, the NSCustomView object sends an alloc and initWithFrame: message to the real view class and then swaps the resulting view object in for itself. The net effect is that the real view object handles subsequent interactions during the nib-loading process.
Custom views in iOS do not use the initWithFrame: method for initialization.
c. Custom objects other than those described in the preceding steps receive an init message.
3. It reestablishes all connections (actions, outlets, and bindings) between objects in the nib file. This includes connections to File’s Owner and other placeholder objects. The approach for establishing connections differs depending on the platform:
• Outlet connections
In OS X, the nib-loading code tries to reconnect outlets using the object’s own methods first. For each outlet, Cocoa looks for a method of the form setOutletName: and calls it if such a method is present. If it cannot find such a method, Cocoa searches the object for an instance variable with the corresponding outlet name and tries to set the value directly. If the instance variable cannot be found, no connection is created.
In OS X v10.5 and later, setting an outlet also generates a key-value observing (KVO) notification for any registered observers. These notifications may occur before all inter-object connections are reestablished and definitely occur before any awakeFromNib methods of the objects have been called. Prior to v10.5, these notifications are not generated. For more information about KVO notifications, see Key-Value Observing Programming Guide.
In iOS, the nib-loading code uses the setValue:forKey: method to reconnect each outlet. That method similarly looks for an appropriate accessor method and falls back on other means when that fails. For more information about how this method sets values, see its description in NSKeyValueCoding Protocol Reference.
Setting an outlet in iOS also generates a KVO notification for any registered observers. These notifications may occur before all inter-object connections are reestablished and definitely occur before any awakeFromNib methods of the objects have been called. For more information about KVO notifications, see Key-Value Observing Programming Guide.
• Action connections
In OS X, the nib-loading code uses the source object’s setTarget: and setAction: methods to establish the connection to the target object. If the target object does not respond to the action method, no connection is created. If the target object is nil, the action is handled by the responder chain.
In iOS, the nib-loading code uses the addTarget:action:forControlEvents: method of the UIControl object to configure the action. If the target is nil, the action is handled by the responder chain.
• Bindings
In OS X, Cocoa uses the bind:toObject:withKeyPath:options: method of the source object to create the connection between it and its target object.
Bindings are not supported in iOS.
4. It sends an awakeFromNib message to the appropriate objects in the nib file that define the matching selector:
• In OS X, this message is sent to any interface objects that define the method. It is also sent to the File’s Owner and any placeholder objects that define it as well.
• In iOS, this message is sent only to the interface objects that were instantiated by the nib-loading code. It is not sent to File’s Owner, First Responder, or any other placeholder objects.
5. It displays any windows whose “Visible at launch time” attribute was enabled in the nib file.