Objective-C basic tutorials (6)

Source: Internet
Author: User

Chapter 4 source file organization
All the projects we have discussed so far put all the source code into the main. M file. The main () function of the class, @ interface and @ implementation are all inserted into the same file. This structure is no problem for small programs and simple applications, but it is not suitable for large projects. As the program grows, the file content increases, and information retrieval becomes increasingly difficult.
Think back to your student age. Instead of placing all the final papers in the same file, you will archive each paper separately and create an easy-to-understand file name.
Splitting a program into multiple small files can help you quickly find important code, and others can get a general idea when viewing the project. In addition, you can easily put the code into multiple files and send interesting class code to your friends: you only need to package a few of the files without packaging the entire project. This chapter describes how to split program code into different files.
Splitting interface and implementation
As mentioned above, the source code of the objective-C class is divided into two parts. Some interfaces are used to display the class structure. The Interface contains all the information required to use this class. After the compiler compiles the @ Interface part, you can use the object of this class, call the class method, compose the object to other classes, and create a subclass.
Another component of source code is implementation. The @ implementation section tells the objective-C compiler how to make the class work. This part of the code implements the method declared by the interface.
In the definition of a class, the code is naturally split into two parts: interface and implementation, so the class code is usually put in two files respectively. Code of the interface for storing a file: @ interface command of the class, public struct definition, Enum constant, # defines, and extern global variable. Since objective-C inherits the characteristics of C, the above Code is usually put in the header file. The header file name is the same as the class name, but it is suffixed with. h. For example, the header file of the engine class is named engine. h, and the header file name of the circle class is circle. h.
All the implementation content, such as the @ implementation command of the class, the definition of global variables, and the private struct are put in the same name as the class but. in a file with the suffix M (sometimes called. M file ). The implementation files of the above two classes will be named engine. M and circle. M.
If. if mm is used as the file extension, the compiler will think that you are using objective-C ++ to write code, so that you can use C ++ and objective-C for programming at the same time.
Create a file in xcode
When a new class is created, xcode automatically generates the. h and. M files. After selecting File> New file in xcode, a window is displayed, listing the file types that can be created by xcode.
Select the objective-C class and click Next. In another window, enter the class name.
You can also select the parent class of the newly created class (nsobject by default ). Each class must have a parent class (nsobject has no parent class and is the parent class of all classes ). You can specify the parent class of the new class in the drop-down menu. If you do not have the desired parent class in the drop-down menu, you can directly enter the class name.
After clicking the next button, xcode will ask you where to store the file. It is best to select the directory where other files are located in the current project.
In addition, you will see interesting things. For example, you can select the group in which the new file is put ). At present, we will not discuss the concept of target in detail, just by the way: complex projects can have multiple targets. Their source files are configured differently and their building rules are also different.
After the new class is created, xcode adds the corresponding files to the project and displays them in the project window.
In xcode, there is a group with the same name as the project, and all files are placed in folders in the group. (You can browse the construction of project files in the project navigator .) These folders (called groups in xcode) help you organize source files in your project. For example, you can create a group to store the user interface class, and then create a group to store the data processing class, so that your project will be easier to browse. When setting a group, xcode does not move files or create directories on the hard disk. Group relationships are just a wonderful feature managed by xcode. Of course, if you want to, you can set a group to point to a specific directory in the file system. xcode will help you put the new file into this directory.
Split the car program
First, you must create two classes inherited from nsobject: Tire and engine. Then copy the declaration and implementation of tire and engine classes in Main. m to the corresponding. h and. m Files respectively. The tire class code is posted here. The engine class is similar to this:
Tire. h
# Import <Foundation/Foundation. h>

@ Interface tire: nsobject

@ End
Tire. m
# Import "tire. H"

@ Implementation tire

-(Nsstring *) Description {
Return (@ "I Am a tire ");
} // Description

@ End // tire
The interesting code here is # import in tire. M. It does not import Foundation. h, but tire. h. In fact, this is a standard process. It will basically be written in the projects you create later (. M files must be # import corresponding. H files ). The compiler needs to know the instance variable configuration in the class to generate the appropriate code, but it does not know who the header file matches with the. M file. Therefore, we need to import a. h file. If an error message such as "cannot find interface declaration for tire" (the Interface Definition of the tire class cannot be found) is encountered during program compilation, it is usually because you forget to use the # import Class header file.

Note: There are two methods to import the header file: quotation marks or angle brackets. For example, # import <Cocoa/cocoa. h> and # import "tire. H ". The statements with Angle brackets are used to import system header files, while the statements with quotation marks indicate that the local header files of the project are imported. If the header file name you see is enclosed in angle brackets, the header file is read-only for your project because it belongs to the system. If the header file name is enclosed in quotation marks, You can edit it.
Now, repeat the preceding steps to create the slant6 class and allweatherradial class. At this time, the program may report errors, which may be caused by the slant6 and allweatherradial classes not importing header files of the engine and tire classes. manually add the engine. H and tire. h file # import to the corresponding subclass header file (. h file. The following lists the imported header files in various types of files:
Tire. h:
# Import <Foundation/Foundation. h>
Tire. M:
# Import "tire. H"
Engine. h
# Import <Foundation/Foundation. h>
Engine. m
# Import "engine. H"
Slant6.h
# Import "engine. H"
Slant6.m
# Import "slant6.h"
Allweatherradial. h
# Import "tire. H"
Allweatherradial. m
# Import "allweatherradial. H"
Car. h
# Import "engine. H"
# Import "tire. H"
Car. m
# Import "car. H"
Main. m
# Import <Foundation/Foundation. h>
# Import "car. H"
# Import "slant6.h"
# Import "allweatherradial. H"
Cross-file dependency
Dependency is a relationship between two entities. Dependencies often occur during programming and development. The dependency can exist between two classes. For example, the slant6 class is dependent on the engine class because of its inheritance. If the engine class changes, such as adding a new instance variable, you need to re-compile slant6 to adapt to this change.
The dependency can also exist between two or more files. Car. h depends on the tire. hengine. h file. If either of the two files has changed, recompile car. m to adapt to this change.
Importing a header file establishes a close dependency between the header file and the source file. If the header file has any changes, all files dependent on it must be re-compiled. It takes a long time to use a bunch of super-performance hosts.
Because dependencies are passed and header files can also be mutually dependent, re-compilation is more serious. However, although recompilation takes a long time, at least xcode can help you record all dependencies.
Notice on re-Compiling
Objective-C provides a method to reduce the negative impact of re-compilation caused by dependency. The cause of dependency problems is that the objective-C compiler requires some information to work. But in fact, the compiler sometimes only needs to know the class name, and does not need to know too much.
For example, after an object is composite, the composite points to the object through a pointer. This works because all objective-C objects use the dynamically allocated memory. The compiler only needs to know that this is a class, and then it will know the size of the instance variable, that is, the size of a pointer, no need to know more.
We used the # import method to complete the car. h file and car. M file, but it also produces obvious side effects of re-compilation, so now I can use another method: @ class, this method is enough to inform the compiler of all the information required to process the @ Interface part of the car class. However, this method does not work in car. M. Because we need to create a specific engine and tire instance in car. m, the compiler must know all the content of these two classes. In car. m, we can only use import (# import ).
Note: @ Class creates a forward reference. This is to tell the compiler: "Believe me, you will naturally know what this class is, but now, you know enough ."
If there is a circular dependency, @ class is also useful. That is, Class A uses Class B, and Class B also uses Class. If you try to use the # import statement to make the two classes reference each other, a compilation error will occur. However, if @ Class B is used in a. h file and @ Class A is used in B. H, the two classes can be referenced from each other.
Let the car run for a while

Car. m requires more information about tire and engine, so tire. h and engine. H should be imported into car. M. (Silent voice: I have a problem here, because I didn't set the car before. the init method code in M is deleted, so even in the car. tire. H and engine. h. The init method still reports an error. I don't know why. Later, I had to delete init .) The modified car. m code is as follows:
//
// Car. m
// Carparts
//
// Created by mouyong on 13-7-6.
// Copyright (c) 2013 mouyong. All rights reserved.
//

# Import "car. H"
# Import "engine. H"
# Import "tire. H"

@ Implementation car

-(Void) print {
Nslog (@ "% @", engine );
Nslog (@ "% @", tires [0]);
Nslog (@ "% @", tires [1]);
Nslog (@ "% @", tires [2]);
Nslog (@ "% @", tires [3]);
} // Print
-(Engine *) engine {
Return engine;
} // Engine
-(Void) setengine :( engine *) newengine {
Engine = newengine;
} // Setengine
-(Tire *) tireatindex :( INT) index {
If (index <0 | index> 3 ){
Nslog (@ "Incorrect index value % d! ", Index );
Exit (1 );
}
Return (TIRES [Index]);
} // Tireatindex
-(Void) settire :( tire *) tire atindex :( INT) index {
If (index <0 | index> 3 ){
Nslog (@ "Incorrect index value % d! ", Index );
Exit (1 );
}
Tires [Index] = tire;
} // Settire: atindex

@ End // car
Import and inherit
Slant6 and allweatherradial inherit from the classes we created: slant6 inherits from engine and allweatherradial inherits from tire. Therefore, @ class cannot be used in header files. You can only # import "engine. H" in slant6.h and # import "tire. H" in allweatherradial. h ".
Why? The compiler must first know all the details about the parent class to compile @ interface for the subclass. It needs to know the configuration of instance variables in the parent class.
Finally, only the # import command and a single function are left in Main. h. As follows:
//
// Main. m
// Carparts
// Relationship between classes and classes: Composite
// Created by mouyong on 13-6-23.
// Copyright (c) 2013 mouyong. All rights reserved.
//

# Import <Foundation/Foundation. h>
# Import "car. H"
# Import "slant6.h"
# Import "allweatherradial. H"

Int main (INT argc, const char * argv [])
{

Car * car;
Car = [Car new];
Engine * Engine = [slant6 new];
[Car setengine: Engine];
For (INT I = 0; I <4; I ++ ){
Tire * tire = [allweatherradial new];
[Car settire: Tire atindex: I];
}
[Car print];
Return 0;
} // Main
Summary
In this chapter, we learned how to use multiple files to organize source code. Generally, each class has two files: the header file containing the class @ interface and the. M file containing @ implementation. You can use the # import command to import the header file to obtain the function of the class. During the learning process, we understand the dependency between files. In this relationship, the header file or source file must use the information in another header file. Too messy File Import will prolong the Compilation Time and lead to unnecessary repeated compilation, and cleverly use the @ Class command to tell the compiler "Trust me, in the end, you will surely understand the class of this name, which can reduce the number of header files that must be imported and shorten the Compilation Time. (Speak silently: In addition, due to the scalability of the Import and the automatic check of coaca, we can import each header file only once. Even if the import is repeated, we don't have to worry too much about occupying the memory, because coaca will help us merge repeated imports, but we do not know that this mechanism is unreliable)
Next, let's take a look at some interesting xcode functions. See the next chapter.

Related Article

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.