As with C and C + +, Objective-c also uses the header file and the implementation file (implementation files) to partition the code. The standard way to write "class" in the Objective-c language is to create two files with the name of the class name, respectively, and the suffix of. h for the header file suffix. After you have created a class, its code looks like this:
// EOCPerson.h
#import <Foundation/Foundation.h>
@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@end
// EOCPerson.m
#import "EOCPerson.h"
@implementation EOCPerson
// Implementation of methods
@end
It is almost necessary to introduce Foundation.h in any class written in objective-c language. If this file is not introduced in the class itself, then the "Base header file" corresponding to the framework of its superclass should be introduced. For example, when you create an iOS application, you typically inherit the Uiviewcontroller class. The header files of these subclasses need to be introduced into the UIKit.h. Now it seems that the Eocperson class is OK. Its header file introduces the entire foundation framework, but this is not a problem. If this class inherits from a class in the foundation framework, then the consumer of the Eocperson Class (consumer)
Many of the content in its base class may be used. The same is true of those classes that inherit from Uiviewcontroller, whose users may use most of the content in Uikit.
Over time, you may have created a new class named Eocemployer, and then you might think that each Eocperson instance should have a eocemployer. Then, add a property directly to it:
// EOCPerson.h
#import <Foundation/Foundation.h>
@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) EOCEmployer *employer;
@end
However, the problem with this is that the Eocemployer class is not visible when compiling a EOCPerson.h file. It is inconvenient to force developers to introduce EOCEMPLOYER.H when introducing EOCPerson.h, so common
The idea is to add the following line to the EOCPerson.h:
#import "EOCEmployer.h"
This approach is feasible, but not elegant enough. When compiling a file that uses the Eocperson class, you do not need to know
Eocemployer all the details of the class, just know that there is a class called Eocemployer just fine. Fortunately, there is a way
Can tell the compiler:
@class EOCEmployer;
This is called "forward declaration" (forward declaring) of the class. Now Eocperson's header file has become this:
// EOCPerson.h
#import <Foundation/Foundation.h>
@class EOCEmployer;
@interface EOCPerson : NSObject
@property (nonatomic, copy) NSString *firstName;
@property (nonatomic, copy) NSString *lastName;
@property (nonatomic, strong) EOCEmployer *employer;
@end
The implementation file for the Eocperson class should introduce the header file of the Eocemployer class, because to use the latter, the
You must know all of its interface details. Thus, the implementation file is:
// EOCPerson.m
#import "EOCPerson.h"
#import "EOCEmployer.h"
@implementation EOCPerson
// Implementation of methods
@end
The opportunity to introduce a header file is postponed as far as possible, only when there is a need, so you can reduce the number of header files that the class's users need to introduce. Assuming this example introduces EOCEmployer.h to EOCPerson.h, all the content of EOCEmployer.h is introduced as soon as EOCPerson.h is introduced. If this process persists, a permit is introduced to
More than the basic content, which of course will increase the compilation time.
The forward declaration also solves the problem of two classes referencing one another. Assuming that you want to add new and deleted employee methods to the Eocemployer class, the following definition is added to the header file:
- (void)addEmployee:(EOCPerson*)person;
- (void)removeEmployee:(EOCPerson*)person;
At this point, to compile Eocemployer, the compiler must know the Eocperson class, and to compile Eocperson, you must know Eocemployer. If the header file is introduced in the respective header file, it causes a "circular reference" (Chicken-and-egg situation). When parsing one of the header files, the compiler discovers that it introduces
to another header file, and that header file goes back to referencing the first header file. Using #import instead of # include directives does not cause a dead loop, but this means that one of the two classes cannot be compiled correctly. If you don't believe it, the reader can try it out for himself.
However, it is sometimes necessary to introduce additional header files in the header file. If you write a class that inherits from a superclass, you must introduce a header file that defines that superclass. Similarly, if you want to declare a class that you write to conform to a protocol (protocol), the Protocol must have a full definition and cannot use forward declarations. Forward declarations can only tell the compiler that there is a protocol, and the
compiler knows the methods defined in the protocol.
For example, to inherit a rectangular class from a graphics class and make it conform to the drawing protocol:
// EOCRectangle.h
#import "EOCShape.h"
#import "EOCDrawable.h"
@interface EOCRectangle : EOCShape<EOCDrawable>
@property (nonatomic, assign) float width;
@property (nonatomic, assign) float height;
@end
The second one#importis inevitable. In view of this, it is best to place the agreement in a single header file. If you put the Eocdrawable protocol in a large header file, you will have to introduce that header as soon as you introduce this protocol.
The entire contents of the piece, so that, as stated above, there is a dependency problem, and it increases the compilation
Time.
However some agreements, such as "Entrustment Agreement" (Delegate protocol), do not have to write a separate
The header file. In that case, the agreement only makes sense if it is defined with the class that accepts the agreed-upon delegate. This is the best
This class can be declared in the implementation file, and this implementation code is placed in the "class-continuation
Category "(Class-continuation category). In this case, you can simply introduce the inclusion in the implementation file
The header file of the delegate agreement, without placing it in the public header file. Each time you introduce another header file into your header file, ask yourself if it is necessary to do so. If you can replace the introduction with a forward declaration, then do not introduce. If you must introduce a header file because you want to implement a property, instance variable, or to follow a protocol, you should move it to the class-continuation classification as much as possible. Not only does this reduce compilation time, but it also lowers the dependency level. If the dependencies are too complex, it can be problematic for maintenance, and too complex dependencies can be problematic if you just want to open a part of the code to a public API.
Points:
- Do not introduce a header file unless it is necessary. In general, the forward sound should be used in the header file of a class
Minlaiti and other classes, and introduce the header files of those classes in the implementation file. This can be done to minimize between classes
Coupling (coupling).
- It is sometimes impossible to use forward declarations, such as declaring a class to follow a protocol. In this case, try to move the statement "This class follows an agreement" to the "Class-continuation classification". If not, put the protocol in a single header file and introduce it.
Introduce as few other header files as possible in the header file of the class <<effective objective-c>>