First, the previous review

We have introduced the iOS learning roadmap before, but it was delayed for some time due to some Android development problems. In the following period of time, we will continue to learn the violent road of iOS. According to international practice, the first application is of course our HelloWorld program. So this article will explain the iOS program life cycle through such a simple program, several key objects in the application, the project structure, and finally create an empty project by hand.

Create a simple program HelloWorld

Let’s create a new HelloWorld program with Xcode:



Click next:



This is very similar to creating a new Android application in AndroidStudio. Without further ado, click Next:



Now that the project is set up, let’s get the program running and display a HelloWorld text. There are two ways to do this, and it’s similar in Android, so we’re going to use UILabel to do this. Similar to the TextView control in Android, one way is to write the layout code, one way is to drag the layout file similar to Android. This is written directly in code for convenience and more on drag in the future.

So where do we write the code? The entry here is in the root controller ViewController class:



This entry is similar to the onCreate method of the Activity in Android. We usually initialize a View here. Here we see the code logic is not very complicated, but there are many hidden knowledge points, but it is not the focus of this article, for example, it involves the coordinate problem of iOS, the relationship between views, etc. This is in the later chapters will be introduced in detail View knowledge points to be analyzed. When the code is done, run the program. It’s easy to run:



Directly click the “run” button in the upper left corner, and select the target device for the project to run. The running results are as follows:



As you can see here, a simple HelloWorld is displayed on the 4S device. Okay, so now we get to the big part of today, what we can learn from this simple program.

Three, program knowledge point analysis

First, the entry and life cycle of the program

We all know when we’re developing Android applications that the entry point to an Application is not the onCreate method of the MainActivity or the onCreate method of the Application, but the main method of the ActivityThread, similarly, In iOS, the entrance to an application is also the main method, and the main class is inside the main method:



Every program has a class called main.m, and inside it is a main method, and this method, as we see in C, has the same form as main, and the entry point is right here, so one of the things that’s done here is to delegate the application’s proxy object, the AppDelegate class, That is, you delegate the entire application logic to the AppDelegate class, which in iOS is called a delegate, and in Android we call it a callback mechanism, and then the UIApplicationMain class interacts with the AppDelegate class, for example, for the application’s life cycle, So let’s look at the AppDelegate class:



In this class we can see a number of timed callback methods, this one is associated with the application lifecycle method, the following is an analysis of each method callback timing:

1. Tell the agent to start the basic completion program ready to run

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

2. Tell the agent that the process is started but has not entered state saving

– (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions

3. When an application is about to execute in an inactive state, during which time the application does not receive messages or events, such as a phone call

– (void)applicationWillResignActive:(UIApplication *)application

4. Called when the application is pushed to the background. So to set the background to continue running, you can set it in this function

– (void)applicationDidEnterBackground:(UIApplication *)application

5. Called when the program is about to return to the foreground from the background, which is the opposite of the above method

– (void)applicationWillEnterForeground:(UIApplication *)application

6. When the application is active, this is the reverse of the above method

– (void)applicationDidBecomeActive:(UIApplication *)application

7. When the program is about to exit, it is usually used to save data and do some cleanup before exit

– (void)applicationWillTerminate:(UIApplication *)application

8. When the application receives a memory warning callback method

-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application

After looking at the above lifecycle callback methods, you might think that this is very similar to the Activity class in Android, rather than the Application class. In Android, there are usually three physical buttons related to the lifecycle of an Activity. In iOS, there’s only one Home button, so the life cycle here is pretty straightforward.

Second, the application window

Above is introduced over the iOS program related to the life cycle of class AppDelegate, below also need to continue to analysis, how to link the ViewController class, to show the HelloWorld?

First, we print a log in the callback method after the program is started, and print out the current application and controller:



Note: In iOS, the method of printing logs is similar to that of Android. It can be printed using a string format. Generally, the placeholder for printing objects is %@. Here to say a few more words, is the general print basic type format is as follows:

Integer type %d,% I

% hd short integer

% % ld, LLD long integer

%u is an unsigned integer

%f float and double

%0.2f Precision floating point number with only two decimal digits reserved

%x is a 32-bit unsigned int printed in hexadecimal with the numbers 0-9, lowercase A-f.

%X is A 32-bit unsigned int printed in hexadecimal numbers 0-9, uppercase A-f; %X is A 32-bit unsigned int printed in hexadecimal numbers 0-9, uppercase A-f.

% o octal

%p pointer address

%s char* is a string of type

%c char Indicates the character type

% C unichar type

And these types of print format need not back, use more natural remember, and here the most used should be % I,% S,%p,% C,%f these several.

The print result is as follows:



See what lifecycle callback methods are executed when an application is started, and see that the root controller is the ViewController class object from which we added the HelloWorld control above. Then this raises two objects: one is the self. The window object, is a window. The rootViewController object. Let’s first look at self.window, which is actually a UIWindow type. As with Android, one application for one window is the basis for displaying a View later.

Usually, an application corresponds to a UIWindow, which is the application Window, but this can not be said too absolutely, because later, whether Android or iOS will appear multi-screen development mode, then there will be more than one Window. UIWindow is a special View that inherits from THE UIView class. You can add View controls directly to it, and you can manipulate it as you would with a View:



As stated above, an application can only have one UIWindow, but we can define multiple UIWindows, and then set the specified UIWindow as the main window, and that’s fine. To make that window the main window and show it, just call the makeKeyAndVisible method.

Third, the application’s root controller

Now, UIViewController is the iOS equivalent of an Activity on Android. It controls the display function of a View. It’s the carrier of each page in an application. In Android, an application has a default or main Activity. In iOS, it has a root controller, and this root controller is the value of the rootViewController property that needs to be set to the unique window of the application, namely UIWindow. There are also several lifecycle methods for controllers. The most common and dominant one is the one used after the View is loaded:

– (void)viewDidLoad

This method is similar to the Activity’s onCreate method, where we add views ourselves. From the example above we can see that in this method we define a UILabel property, and each controller has a very important property called the parent View, so we can add any View that we need to add by using the addSubView method.

Note:

Adding a View to iOS is very easy and convenient, because any control including the UIWindow above inherits from the UIView class, and those controls can add any other controls without any restrictions, like you can add a label UILabel to a button UIButton and that’s fine, In Android, if a control wants to add a child View, it must inherit the ViewGroup, such as the layout class we commonly use. This seems to be much easier on iOS than Android.

In Android, a jump between activities is performed with an Intent, but in iOS, there is no such mechanism. Instead, a specific controller is used to manage the class. It is generally used for navigation controller and TAB controller to do management, specific knowledge to accept the controller in detail.

Fourth, summarize the four object relations

This concludes the analysis of four very important objects in an iOS application: UIApplicationDelegate, UIWindow, UIViewController, and UIView



From this diagram, you can see that an application must contain the application’s delegate object UIAppDelegate class, and the application window UIWindow class. And then the window also has a root controller page UIViewController class, and each controller has a parent View that displays the UI, and the root controller is no exception. Finally, each controller is associated with a parent View that displays the UI for each page.



Create an empty project

Once we know the structure of an application and the key objects, let’s create an empty project by hand and then create the four key objects ourselves. Since Xcode8 no longer supports creating an empty project, to create an empty project, we can create a new project and delete all the classes, so it looks like this:



Step 1: Create a new UIViewController root controller



Be sure to select the CocoaTouch Class file:



Here we are actually equivalent to the completion of a simple application, the following need to set the window information and root controller information in the application callback method:



When you run the application, you can see a red patch of the application:



The basic elements of an application must be UIApplicationDelegate and UIWindow, and the root controller. This is a simple application, but in practice it must contain multiple controllers. And each root controller has a View layout file, so let’s start creating the corresponding View information by hand. Of course, you can manually encode a View in the controller’s callback method, but in iOS, just like on Android, each controller has its own layout file, called xiB.

Step 2: Create a XIB file



Select the next step and name it root.xib



When new is created, you can see nothing:



We need to create it step by step.

Step 3: Associate the XIB and controller

Then we set the File’ Owner of the current XIB as our root controller. We must set the File’ Owner of the xiB, otherwise we will get an error.



Each layout File is associated with an Activity. The same principle applies here. A XIB must rely on a controller, so the File’s Owner can be set to the corresponding controller.

Note:

The XIB file on iOS is a little different from the layout file on Android. In this case, you can not only set the layout format of the view, but we’ll see an example later, where you can include some special objects, and we’ll see how to put controllers, Windows, and other objects into a XIB. An application can be created without writing any code at all, but what’s the difference between xiB and stroyBoard created by Xcode by default? For example, if I want to create a controller, I need to create a corresponding XIB file. If there are multiple controller pages in a project, there will be multiple XIB files in the project, which may be difficult to manage. Stroyborad can manage all of these files together, but I know from other iOS veterans that this is actually a matter of project and individual development habits, and it is not strongly required to use StroyBorad.

Step 4: Add the parent View to the XIB

We need to add a View to the xiB file. If we do not set this View, we will run the program with an error. Adding a View is easy.



Search for the View control and, once found, drag it directly into the XIB content. After that, we also need to associate the view property of the controller with the view control, otherwise we will also report an error. This is easy, for Xcode development tools, just a drag and drop of the connection. As shown below:



Note:

In iOS, there is a handy way to assign an object and then add an event to the control. Sometimes you can use drag as a shortcut, but only if you set the property to IBOutlet. After setting this property, you can see a small circle in front of the property:



And then if you want to assign that property to it, you just drag it to the specified object, so here you can also see the difference between the xiB in iOS and the Layout file in Android. Another is the IBAction feature, which adds events to the control. This is usually added to a method that appears in the drag list. For example, we define a method in the controller:



Here you can see that there is also a small circle. Let’s go back to the File’s Owner in xiB:



As you can see here, when you drag the right-hand plus circle of the doClick method onto a UIButton control, you get this screen that lists multiple events. We can select one of these to indicate that the UIButton control’s event triggered method is doClick. The findViewById method is used to call back to a set of events. Of course, there are open source frameworks in Android that do this, mostly with annotations. Unordered findViewById assignment and add events. But I don’t really like using this framework, I think native is the best!

Step 5: Load the XIB file

Ok, so now we have a new root controller and the corresponding XIB file, so if we want the controller to display the XIB content, we need to do some work is to manually load the XIB file, the above connection is simple to establish the relationship, we need to write our own code to load, SetContentView = setContentView = setContentView = setContentView



The controller provides an initWithNibName:bundle: method that explicitly loads a XIB file. The xiB file name does not carry a suffix, and the xiB file name is passed in as a second argument to indicate the xiB file’s path. If passed in as nil, the xiB file is found in the root directory of the project.

After setting up the controller to load the XIB code, we can now run the program:



When we saw the effect, we realized that not only could we add the View manually in the controller, but we could also use xiB files to layout the page.

Here we will hand in hand a new simple project, in this process we will understand more about the relationship between the four important objects in the program, the following to summarize:

1, UIAppDelegate class

This class is used to manage the application lifecycle and callback methods for events, and each application will have one of these classes.

2, UIWindow classes

This class is basically a window that displays the UI of your application. It’s actually a special UIView that you can manipulate like a control, and each application has a unique main window, the window property in the UIAppDelegate class.

3, UIViewController class

This class is the function class that manages each page in the application. It is very similar to the Activity class in Android. An application usually contains multiple controllers, but there must be a root controller, which should be set to the rootViewController property value of UIWindow. For each controller, the code layout is added in the viewDidLoaded method. For each controller, the xiB layout file is loaded manually using the controller’s initWithNibName: Bundle: method.

4, UIView class

This class is actually the parent of every control in iOS, but every controller has a parent View, and this is UIView, and it’s usually set to the View property value of UIViewController.

Five, knowledge supplement

First, parse the XIB file

Xib file parsing process:

1> Create all the Objects below

2> Set up the association between all Objects and File’s Owner

As mentioned in the previous introduction to XIB, xiB can add not only control views, but also various objects. For example, here we can add UIWindow and UIViewController objects:

See, a XIB can actually manage all of the objects in a simple application, and then we can just look at the relationships between those objects.

Second, apply the four object setting relations and steps

1> Create the controller by calling the init method or initWithNibName:bundle: method

self.viewController = [[RootViewController alloc] init]; (The view inside the controller is not initialized immediately after it is created.)

2> Set the controller to the root controller of UIWindow

self.window.rootViewController = self.viewController; (The view of the controller is not added to the window after setting the root controller)

3> Display the window and add the controller view to the window

[self.window makeKeyAndVisible];

Initialize the view of the controller by calling the controller’s loadView first (this can be created by xib file \ this can be created by code)



Third, UIViewController lifecycle method call order


1> After the view is initialized, the controller will be calledviewDidLoadmethods

2> After the view is initialized, the view of the root controller is added to the window

3> The controller is called when the view is about to be added to the windowviewWillAppear:methods

4> The controller is called when the view has been added to the windowviewDidAppear:methods

5> This is called when the controller’s view is about to be removed from the windowviewWillDisappear:methods

6> If the controller view has been removed from the window, the controller will be calledviewDidDisappear:methods

7> The controller is called when it receives a memory warningdidReceiveMemoryWarningmethods

DidReceiveMemoryWarning method is the default implementation is: if the controller of the view is not displayed in the window, that is the controller. The superview is nil, the system will destroy the view of the controller.

8> The controller will be called after the destructionviewDidUnloadmethods

9> If the view of the controller was destroyed before due to a memory warning and you need to access the view again, the previous steps will be repeated to initialize the view

Six, summarized

The content of this article is a little bit more, but it is the beginning of our development of iOS, but also our first iOS program, we can learn from this simple program to a program involved in the life cycle and several important objects, the relationship between them and so on. At the same time, I also understand the interface layout function and two methods in iOS. I’m going to continue to talk about controllers in iOS.

More:Click here to

Pay attention to wechat public number, the latest technology dry goods real-time push