1. Introduction
Both MAC OS app and ios app development are inseparable from the creation of UI, which can be divided into two types: code handwritten UI and layout and the use of a single XIB file to organize viewController or View. This article is not about the pros and cons of these two UI methods, but about “what happens” after xiB file organization viewController and after load NIB file. If you need to know about the drawbacks of both approaches to creating UI, check out These two articles on which code to write UI, xiB vs. StoryBoard, some tips on Interface Builder, and some of the debate over storyboards. Or read A Case For Using Storyboards on iOS.
2. Start with a line of code
Let’s look at the code that creates a viewController object.
//method description
/*Returns a view controller object initialized to the nib file in the specified bundle. */
myViewController = [myViewController initWithNibName:@"myViewController" bundle:nil];
Copy the code
This method is declared as follows:
- (instancetype)initWithNibName:(NSNibName)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil;
nibNameOrNil(typedef NSString *NSNibName): The name of the nib file, without any leading path information.
nibBundleOrNil:The bundle in which to search for the nib file. If you specify `nil`, this method looks for the nib file in the main bundle.
Copy the code
Create an object of class myViewController that looks for a NIB file named myViewController from the specified bundle. The owner of the NIB file must be set to (in Xcode) myViewController. Layout your View, window, or other UI controls by organizing xiB files. (XiB and NIb can be understood as the same thing. See What is a NIb?) . Xib files are created with Xcode, objects are created on them, and configurations (such as width, height, background color, and Constraint between views) are set so that when loading xiB files, these objects can be instantiated in memory, and configurations made in Xcode can be copied.
3. Analyze xiB files
There are many types of objects that can be contained in a XIB file. This section describes the different types of objects in a XIB file.
3.1 Interface Objects
Interface Objects are user interface objects, such as Windows, Views, Controles, and Menus. The image below, for example, shows some visual objects in the myViewController.xib file.
In addition to visual objects that can be added to XIB files, non-visual objects can also be added to XIB files, such as Controller Objects. See Controller Objects for more informationThe document. These Controller objects can manage visual objects, and of course controller objects can also be created in code. In the xiB file of the following image, the Popover View Controller object is created to manage the Popover visual object.
3.2 the File ‘s Owner
File’s Owner Object The most important Object in a XIB File, which is different from the interface Object. File’s Owner Object is a placeholder Object, and it won’t be created when the xiB File is loaded. In fact, when loading the Xib file, we need to pass it an object as the file’s Owner object. At this point, however, I’d like to introduce a file’s Owner option in Xcode’s XIb file, as shown below.You can see that in the top right corner, set the Class of File’s Owner to myViewController. So at this point you drag the interface object outlet to the File’s Owner and you can see that there are several options.
MainView is defined in myViewController.m.
The reason this object is important is that it is between your code and the XIB fileThe connection bridgeWhen you load the xib file, the load Xib file code reestablishes these connections (which will be covered later).
3.3 the Top – Level Objects
After loading the xib file, CoCoa will recreate the Graph of Objects you created in XCode. The Object Graph contains all the Windows, Views, and Custom Objects that you created in the XIB file. So Top Level Objects refers to a subset of these Objects, and there is no parent object. Generally speaking, top level objects include Windows, Menu bars and Custom Controller objects (File’s Owner object is not a Top level object).
3.4 Image and Sound Resource
In Xcode, you can use image and audio resources, such as the contents of the ImageView to specify images, such as the following. In the XIB file, you add an ImageView and it uses image resources. Xcode’s library provides access to image and audio resources by linking xiB files to these resources. Xib files do not store resources directly, but refer to the name of the file to be stored so that these resources can be found after loading xib files.
4. Nib File Design Guidelines
When you create a XIB file, you need to think about how to use the objects created in the XIB file. While a very simple application can store all the user interface objects in a single XIB file, for most applications, organize your user interface using multiple XIB files. This has at least two advantages: creating small XIB files allows you to load only what you need, which increases speed. And when you have a problem, you can easily locate the problem. When creating xiB files, you can follow these principles:
- Design xiB files with lazy loading in mind, which is the xiB file that loads only the objects you need.
- In the main XIb file of an OS X application, consider that the XIB file should store only the application menu and delegate Objects. You don’t need any Windows or User-Interface elements that you won’t use after startup.
- Store reused user interface components in a separate XIB file.
- Windows or Menu, which are used occasionally, can simply be stored in a separate XIB file and loaded into memory when needed.
- The File’s Owner becomes a single object that links between objects in the XIb File and objects outside the XIB File.
5 Load Xib File again
When a XIb file is loaded into memory, nib-loading code has several steps to ensure that the object in the XIb file is created and initialized correctly. Knowing these steps will help you write controller Code to manage user interface objects. Its process is shown in the figure below:
- Load xiB FLIE file contents and referenced resources, such as images and audio, into memory.
- Xib file The raw data of the entire Object Graph is loaded into memory, but not unarchived. (Note: All objects created in xiB files are considered encoded and need to be unarchived by the corresponding decode method. In particular, a XIB file is stored on disk as a XIB file, but loaded in memory as an instance object of the NSNib class.)
- The image resource is loaded into memory
- The audio resource is loaded into memory
- Unarchives NIB Object Graph raw data and instantiated objects. Each object is initialized according to how it is enoded in the Archive. The main principles are as follows:
- By default, objects
initWithCoder
To initialize the message. In OS X, views, cells, Menus, and View Controller are all sentinitWithCoder
Message is initialized. - Custom Views is used by
initWithFrame
Initialization. Customs Views is a subclass of NSView and there is no code implementation in Xcode. - All but the custom views above are initialized by sending an init message.
- Re-establish all connections, including actions, outlets and bindings between objects in niB files. This includes associating with File’s Owner and other placeholder objects. The way these connections are established varies from platform to platform.
-
In OS X, nib-Loading first tries to recreate an Outlet connection using the object’s own method. For each Outlet, CoCoa looks for a method of the form setOutletName:, If it exists, it is called. If it cannot be found, CoCoa searches for the instance variable in the object, and if the instance variable has a matching outlet name, attempts to set the value of the instance variable directly to the object. If it is not found, the connection is not established. If an outlet is set, a key-value observing(KVO) notification will be set up for all register Observers. These notifications may occur before all connections between objects are re-established, and certainly before any awakeFromNib methods of the object are called.
-
Action connections
In OS X, nib-Loading code uses the Soucre Object’s setTarget: and setAction: methods to connect to target objects. If the target object does not respond to the Action Method, the connection will not be established. If the target object is nil, the action is answered by the responder chain.
- Bindings
In OS X environment, CoCoa use the source object to bind: toObject: withKeyPath: options: to build it and its target, the connection between the object.
- send awakeFromNib message
In OS X, this message is sent to all interface objects that define the method. Also send File’s Owner and other placeholder objects. There is no guarantee of the order in which nib-loading code calls awakeFromNib. Cocoa tries to call File’s Owner’s awakeFromNib method last, but this behavior is not guaranteed. So when you need to read and write objects from niB files, it’s best to do so after the load-NIb call returns. At this point all objects have been created, initialized, and can be safely accessed.
- The final niB file that is visible after startup with the option true is displayed.
6. Manage the life cycle of objects in Xib Files
When you load xib files every time you use the NSBundle or NSNib class. Objects in the XIB file are copied by default (each load of the XIB file does not reuse the objects created by the previous load). That is, when you load xiB files, you need to manage the life cycle of those objects so that they can be recycled properly when you don’t need them. You need a strong reference to top level objects. Weak references that are not top level objects can use weak references because they are held by their parents. Strong outlets generally point to framework classes. So NSViewController’s view outlet and ns Windows controller’s window outlet. Here’s an example to illustrate. In the myViewController.xib file, we create a Custom View with an NSTextField object and an NSImageView object. Create outlets separately (in myViewController.m). You can see that mainView Outlet uses strong and textField outlet uses weak. Because mainView corresponds to a top-level object and textField belongs to its child, weak can be used. When the mainView object is not destroyed, the textField object is not destroyed, so using weak ensures its lifetime,And can reduce the error of circular reference.
One thing to note is that when a subview in your Object Graph needs to be removed, its outelet should be strong, because its life cycle needs to be managed separately.