Key processes for Viewcontroller

Source: Internet
Author: User

This article reproduced from: http://www.cocoachina.com/ios/20151216/14705.html. Please contact us if there is infringement.

In the recent resolution of a problem, found in viewdiddisappear to get self.navigationcontroller empty. Suddenly realize that there are some details in the life cycle of VC need to pay attention to. Moreover, in recent times, there has been some reflection on the programming idea of modeling processes based on process (life cycle is a special process). So summed up the VC life cycle of some problems.

Let's say something more abstract, about process modeling. For the same object, it often has a different process in the various business scenarios. In other words, it may be in multiple processes for an object. For example, we take a VC to say:

    1. Each OC instance has its own life cycle-creating, using, destroying

    2. And for the VC in dealing with memory problems, there are its unique viewdidload, and other processes

    3. In the processing of the page display, there are viewwillappear and other processes

    4. ...

In a process, each process (typically represented by a function) has its own special responsibilities. For example, Alloc is used for non-matching memory and Init is used to initialize memory. And what we do in these functions must be matched as much as possible with the function's responsibilities. A well-designed process (usually presented in the form of a set of functions) is like a plug-in. Each of the above sockets has its own type, and if you plug it in, there may be a danger of burning the fuse. For example, you alloc in the hard to do dealloc things. From the point of view of design pattern, this kind of thought is called "inversion of Control", which is the common technique of designing frame, and the function is accomplished by restricting the usage of the user. When we use frameworks such as uikit, we naturally accept this "inversion of control" as a user. And be able to do the right thing in the right place. In a word, it is: appropriate.

At the same time, I want to illustrate some of the VC's life processes and their use of details of things. It can also inspire readers to rethink the idea of programming based on process modeling. This thinking reflects the use of some processes in other libraries in everyday programming. Even when you are programming, you can also pay attention to the use of this way.

All right, let's start by looking at what processes a VC has to pay attention to. BTW, poor lifting all processes are a time-consuming and laborious task, so they will only pick up a few more critical processes to describe and explain. The most important goal is to be able to inspire you to consider some of the problems of programming with the perspective of Process modeling:), lazy.

Memory usage Flow

VC instances in memory use above, the process and other object instances of the use of similar, all have to go through the following procedures:

Created with initialization--use--destroy

The later elaboration is similar, we first say the process. And then specific to the use of the function. Because when we use a library or framework, the first thing to focus on is his model. Especially the process model. and the specific function is often based on the model, the product of practice down.

(1) Create

Apple uses the idea of two-stage construction in memory processing: two steps to create and initialize.

The core focus of the creation is memory allocation. A chunk of memory is allocated from the stack for use by the object. As for the object, how to use that memory (initialize) is something else. After two steps have been created and initialized, it is possible to give a clean, ready-to-use object instance.

At the time of creation, generally involves the function is: ~ ~ + (instancetype) Alloc + (Instancetype) Allocwithzone: (struct _nszone *) Zone ~ ~ ~ These two functions are system functions, We cannot overload the function. This is what Apple emphasizes in the documentation. Thus, for creating we are just invoking the system functions, there is not much custom work that we need to do.

(2) initialization (RAII)

Initialization is the second step in a two-stage construct, and an object instance is a clean, ready-to-use object only after that step. This idea is something that we can see in many programming languages, such as C + +. Of course, there are many examples of the construction of a section such as C language.

In OC, the initialization allows us to start the object custom operation. Here we need to initialize some of the values of the properties specific to the current class to ensure that the subsequent business logic is normal enough. For example, when we load the VC from the Xib file we use the function:

1 - (instancetype _Nonnull)initWithNibName:(NSString * _Nullable)nibName bundle:(NSBundle * _Nullable)nibBundle

The function will load the interface through the incoming Xib file name and bundle, and initialize the relevant data. This is, of course, a function of the system. And we are more concerned with what we should do here and what we can do.

Say nonsense: To do the initialization of the object instance. The assignment of variables is mainly the operation of values.

For exmaple:

1234567891011 - (instancetype) initWithNibName:(NSString *)nibNameOrNil                          bundle:(NSBundle *)nibBundleOrNil{    self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];    if(!self) {        return self;    }    _payHandler = [BDWalletPayWebHandler new];    _payHandler.enviromentWebViewController = self;    returnself;}

In the above example, we initialize a _payhandler variable in the function. And the attentive reader may find that the value we use to initialize this variable is not externally transmitted, but internally generated. In this way we call it internal initialization. There will naturally be external initialization as well.

    • Internal initialization: The value of the variable is internally generated.

    • External initialization: The value used to initialize the member variable is generated externally and then passed to.

In the actual initialization scenario, we often find this situation: in the design of the class, when encountering the problem of value-added, such as the following problem, we obtained the name of the user through VC1, to VC2 to pass. It is now common practice to leak the name variable in the header file when defining VC2.

123 @interface B : UIViewController@property (strong) NSString* name;@end

And then use it like this:

123 B* vc = [B new];vc.name = @"xx";[self.navigationController push:vc];

This approach, which is poorly encapsulated, can modify the name value in any place where the VC2 instance is held, leading to some very strange logic. And it's often the kind of unpredictable change. It is extremely difficult to find bugs once they appear.

In fact, this situation should be a typical application of external initialization. The better way is that we just use name as an object to initialize the necessary variables, we need to initialize it, then we should provide the corresponding function to initialize. This will keep the package better.

Suggested to take this way later

1234567891011121314151617181920 // .h@interface VC2 : UIViewController- (instancetype) init UNAVAILABLE;-   (instancetype)initWithName:(NSString*)name;@end//.m@interface VC2 : UIViewController (){     NSString* _name;}@end@implatation VC2: UIViewController-   (instancetype)initWithName:(NSString*)name{     self = [superinit];     if(!self) returnself;     _name = name;     returnself;}@end

When declaring variables in the. h file, if you do not need variables that are modified externally, do not burst, make a private variable, if the variable is required to initialize, then write the initialization function ha. Because @property the existence of this grammar, the concept of the scope of OC weakened, resulting in the concept of publick,private,protected and so on is not very clear, from the initialization of this thing is visible. However, these concepts are critical to the robustness of the program. Or should be picked up.

Common functions

123 - init;- (instancetype _Nonnull)initWithNibName:(NSString * _Nullable)nibName bundle:(NSBundle * _Nullable)nibBundle- (instancetype _Nonnull) initWith****

Where the init function is available for all OC objects.

(3) Use

The most important part about using this is that once the object is created and initialized, it can be embedded in a process other than the memory usage process. In the memory flow, what we call use is a series of operations on the memory object in other processes, including and not just: adding and deleting changes.

For details of use, refer to the introduction of other processes.

(4) Destruction

After the mission is completed, the object is naturally destroyed to release the resources it holds. The so-called have to borrow is not difficult to use in the creation process of memory, in the initialization process held by other system resources, at this time to do a unified release. And this is the last time to release, or the object will become a thief, will be permanently stolen resources, such as in the traditional MRC situation, in the init allocation is an array, but in the Dealloc is not released, then the memory of this array is written out.

Here we revisit Raii, where resource acquisition is initialization. Because you got it, you have to release it. Who Pollutes who governs. So the application and release, creation and destruction are must exist in pairs. RAII is a generalized resource management concept that does not have memory.

This problem we in the use of notification, often encounter crash situation, generally because there is no correct removeobser caused by the dirty memory caused. We can think of Addobserve as resource holding, and removeobserver as resource release. This is actually the case, and the function adds and subtract the reference count of the observe. Then for notification this thing can also refer to the above process to consider. But this has to be matched to the business scenario, in some cases accepting notifications can accompany the life cycle of the object, and it is recommended to register the cancellation in Init-dealloc. If you are receiving notifications along with the UI display, it is best to do it in Didappear and Diddisappear (and to add a cancellation in Dealloc, because at navigation poptoroot, Some VCs in the middle do not start disappear functions).

(5) Abnormal

This is not listed in the initial memory flow model, because, in modeling, the first thing to do is to let the whole model work, and then to deal with various boundary problems. If we focus on the processing of the boundary problem, we can enlarge the complexity of the problem without limitation and increase the trouble of processing.

We looked at the underlying memory usage process model and looked at how Apple handled it in exceptional cases.

    • Insufficient initialization of memory

    • return Nil directly

    • Insufficient memory during use

We say here iOS6.0 above situation, after 6.0 viewdidunload and so abandoned, and currently on the market under 6.0 of the machine is fast becoming antique.

When the system encounters a memory warning, the following function of the VC is called, in which we can release some resources that can be created again, such as maintaining the data from the network or the database, and so on. ~~~

(void) didreceivememorywarning {[Super didreceivememorywarning];//Dispose of any resources the can be recreated.} ~ ~ ~

View Management process

Take a look at a larger figure, which is an excerpt from some of the functions Apple currently provides that are related to view control (functions in Uiviewcontroller). And this is also a time series diagram of a call. VC view and the creation of its sub-view is used in this process.

Process explanation

    • Create a root view

When Vc.view is empty, and the first call to Vc.view, the Loadview function is called to load the view.

1234 - (void) loadView{    self.view = [UIView new];}

In this function you can use Self.view = * * To assign a value to the root view, and the recommendation is to only perform the assignment of the root view here. Because once the root view is determined, the external will do some layout of the root view, and if you arbitrarily replace the root view during use, these operations will be difficult to replay. Causes some exceptions to the interface.

    • Initializing a child view on the root view

When Loadview is loaded with the root view, the Viewdidload function of the VC is triggered. This use Self.view already has the value, can addsubview on it.

Here we will generally do some work to initialize the child view, and Addsubview. Pay attention to the layout of things, do not do here, because the system provides us with a special function to do this thing. And this place you get the Self.view frame information is inaccurate. For example, we did not initialize the view in Loadview and set a frame for him. When you get to this viewdidload place, your self.view.frame is {0,0,0,0}. In other words, if you're laying out here, it's probably messy.

123456 - (void)viewDidLoad {    [superviewDidLoad];    _subView = [DZView new];    _subView.backgroundColor = [UIColor whiteColor];    [self.view addSubview:_subView];}
    • Layout

In general, the operation of the root view of the VC is external, such as Uinavigationcontroller to push a VC, the Vc.view.frame will be assigned to control the layout of the VC. And the system of these attempts to control (navigation, and the like), has implemented the Calayer delegate, when the VC root view of the frame changes will receive notification

1 - layoutSublayersOfLayer:

The system's view controller calls these two functions here to notify its current sub-VCs to do the work of the layout:

12 - viewWillLayoutSubviews- viewDidLayoutSubviews

And this sub-VC is generally created by us. Inside these two functions we do the layout operation. One of the two functions is called before the layout of the view itself is done, and one is later. Regardless of the function, the frame or bounds information inside the channel's root view is accurate.

Moreover, if the relative layout of the two functions, the VC will have the root view of the ability to adapt to different screens, while adjusting the root view of the frame, the layout of the entire view can also make corresponding changes.

    • Show process

1234 - viewWillAppear:– viewDidAppear:- viewWillDisappear:- viewDidDisappear:

Understand from the literal meaning of the above function: When the view is loaded, it is displayed on the window, in the user's visible area, or when it leaves the user's visible area. The system will call the VC correlation function to notify this change.

Let's go to see Viewwilldisappear's documentation:

This method was called in response to a view being removed from a view hierarchy. This method is called before the view was actually removed and before any animations be configured.

The above-mentioned display process can be triggered by a system-dependent mechanism:

12345     [vc willMoveToParentViewController:self];    [self addChildViewController:vc];    [self.view addSubview:vc.view];    vc.view.frame = self.view.bounds;    [vc didMoveToParentViewController:self];

Now the default attempt manager Uinavitioncontroller,uitabbarcontroller in the system, and the present way, are guaranteed to use the above mechanism to trigger the response of the display logic. Inside these functions, we can do some and display related business logic.

But when you do business logic, be sure to consider the timing of this function throughout the process and the meaning he represents. Especially in the control flow in each view manager, such as the first mentioned to get the self.navigationcontroller empty problem.

Summarize

For the key process of Viewcontroller, let's talk about memory and view management two. Of course, there are some other processes, it's a little too complicated to say. Hopefully, with the two examples above, we can demonstrate some of the benefits of process modeling in understanding the framework and using the framework. Can use this idea to think about everyday programming problems.

Key processes for Viewcontroller

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.