A lot of friends if they are beginners iOS development, may be some of the load method to get dizzy, but a few of these methods is as a means of iOS programmer must we have below I will do some analysis and comparison on these several methods, and see if I can add the understanding and use of several methods.
Code segment
Alloc/init. Alloc: Creates objects and allocates space. Init /initWithNibName: Initializes objects and data.
- (instancetype)init
// Specify the initialization method. Subclassing UIViewController must call the super implementation of this, even if NIB is not used. (For convenience, the default init method does this for you and specifies nil for both method arguments.)
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
// is called when an object is loaded from a NIB file
- (instancetype)initWithCoder:(NSCoder *)coder;
// The child control is not nil until it needs to be displayed
- (instancetype)initWithFrame:(CGRect)frame;
// This method can be used to create either UIViewController or UIView
- (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary<UINibOptionsKey.id> *)options;
// When the View of the controller is empty, to help the controller load the View. Subclasses should create their custom view hierarchy here and should never be called directly.
- (void)loadView;
Copy the code
UIViewController initialization method
1. Storyboard binding:
This is the default method when we create a new project, the ViewController that’s bound to main.storyboard, and we didn’t use a single line of code when we created it, and that’s also the case when storyboards segue automatically.
2. instantiateViewControllerWithIdentifier:
In this case, you create a new ViewController control in your storyboard and set its id, and then you can use this method to create your controller in your code.
3. loadNibNamed:
This method can be used to create either a ViewController or a UIView.
4. initWithNibName:
[super init] initWithNibName: is automatically called when the controller init method is called. The parameter of this method is the controller class name string.
5. init
Xib: same as 4, but with one more step.
6. init
Pure code: This refers to creating controllers entirely in code, regardless of xiBS or storyboards.
conclusion
The serial number | Create method | callinitWithCode |
callawakeFromNib |
callinitWithNibName |
---|---|---|---|---|
1 | Storyboard binding | is | is | no |
2 | instantiateViewControllerWithIdentifier | is | is | no |
3 | loadNibNamed | is | is | no |
4 | initWithNibName | no | no | Square root |
5 | init | no | no | is |
6 | init | no | no | is |
UIView initialization
Pure code
In general, our custom class inherits from UIView by first adding the child controls needed to the view in the initWithFrame: method. Note that you are only adding to the view and do not set the size of the child controls.
Why do you want toinitWithFrame:
Method rather than ininit
Methods?
Because custom classes are created in pure code, they can be created later using either the init method or the initWithFrame: method, but either way, the initWithFrame: method will be called. Creating child controls in this method ensures that they will be created successfully either way.
Why do you want toinitWithFrame:
Method that just adds the child control to the view without setting the size?
As mentioned earlier, both methods end up calling the initWithFrame: method. If init is used, the frame of the view may be indeterminate:
UIView *myView = [[UIView alloc] init];
myView.frame = CGRectMake(0.0.100.100); .Copy the code
If this is the case, then the frame is undefined in the init method, and if you set the size in the initWithFrame: method, the size of each child control will be 0 because the view’s frame has not been set yet. (You can see that it was set after the init message was sent).
So we should ensure that the view’s frame is set before setting the size of its child controls.
This is done in the layoutSubviews method. This method is called the first time the view is about to be displayed, and then when the size (not position) of the view changes.
Xib way
Using xiB can save the steps of adding child controls and setting the size of child controls in initWithFrame: and layoutSubviews, as well as setting the frame of the View in the View Controller. Because adding child controls and setting the size of child controls and the size of the entire View is done in the XIB. (Note that the position of the entire view is not set yet, it needs to be set in the controller.) We just provide the data interface and override setter methods to display the data.
Note that the class in the XIB is set to be our custom class, so that the custom class is created, not the default parent class.
Of course, with xiB, you need to load the XIB file. There are two ways to load xiB files:
// The first method (more commonly used)
TDView *view = [[[NSBundle mainBundle] loadNibNamed:@"TDView" owner:nil options:nil] firstObject];
// TDView stands for tdView. xib, which represents the xib file corresponding to TDView. This method returns an NSArray, and we take either the first Object or the last (since this array has only one TDView and no other objects) as the TDView to load.
// The second method
UINib *nib = [UINib nibWithNibName:@"TDView" bundle:nil];
NSArray *objectArray = [nib instantiateWithOwner:nil options:nil];
TDView *view = [objectArray firstObject];
Copy the code
supplement
If you create a control in code, the initWithFrame: method must be called at creation time. If the control is created using xib/storyboard, the initWithCoder: method must be called at creation time.
If you access a property like self.button inside initWithCoder:, you’ll find that it’s nil, because the custom control is being initialized, and self.button may not have been assigned. (Self. button is an IBOutlet, IBOutlet is essentially the same thing as Xcode finding this property and UIButton button =… , [self.view addSubview: button], and all these operations are equivalent to the TDView *view = [[TDView alloc] initWithCoder: nil] method. The above code is equivalent to code Xcode to load TDView in storyboard), so initialization in this method will probably fail.
Therefore, it is recommended to do the extra initialization in the awakeFromNib method. Because awakeFromNib is called after initialization, calling properties in this method (IBOutlet) is guaranteed not to be nil.
In fact, by using xiBs to create custom controls, we can encapsulate the xiB loading process into a custom class, exposing only an initialization method so that the outside world doesn’t know how the custom controls were created internally. As follows:
+ (instancetype)viewWithBook:(Book *)book {
TDView *view = [[[NSBundle mainBundle] loadNibNamed: NSStringFromClass(self) owner: nil opetions: nil] firstObject];
view.book = book;
return view;
}
Copy the code
The outside world simply passes in a book with the viewWithBook: method to create a TDView object that only the TDView knows how to create.
If we want to initialize some value either by code or by XIB, then we can pull the initialized code into a method, and then ininitWithFrame:
Methods andawakeFromNib
Method is called separately in the.