文章目录
- #include
- #import
- @class
- @import
- 总结
#include
#include是c\c++中的预处理器指令,用于包含头文件的内容
但是使用#include
可能会出现重复包含文件的问题,因此需要使用(#ifndef/#define/#endif)。
#import
//导入系统头文件使用 < >
#import <UIKit/UIKit.h>
//导入自定义头文件使用 " "
#import "ViewController.h"
#import
是OC中使用的引用头文件的预处理指令,优势在于使用#import可以避免重复导入头文件的问题
什么是重复导入?
A.h中导入了D.h,B.h也导入了D.h,当C.h既导入A.h又导入B.h的时候,C.h中就会重复导入D.h。
而#import确定一个文件中只能导入另一个文件一次,因此#import可以防止文件重复导入。
@class
//声明一个类
@class ViewController;
//一次声明多个类
@class ViewController, MyView, MYBookModel;
@class是OC中的一个前向声明
前向声明的含义是告诉编译器某个类或是某个结构存在,但是具体的定义稍后再提供,使用前向声明后编译器可以使用这个类,但是并不能使用类中的成员变量或是方法
使用@class有几点优势:
- 避免循环依赖
A.h中导入了B.h,同时在A.h中定义如下属性:
@property(nonatomic, strong) B *b;
而B.h又导入了A.h,此时就会形成循环依赖,出现编译错误。
编译器会出现这种情况
- 减少编译时间
如果我们使用#import在.h文件中导入文件,那么每次我们修改文件时都会重新编译导入文件,那么耗时就非常多了,但是如果我们使用@class就不会重新编译导入文件了,因为此时编译器并不知道对应文件的内部实现
具体示例解释
// MyClassB.h
@interface MyClassB : NSObject
@property (nonatomic, strong) NSString *name;
- (void)doSomething;
@end// MyClassA.h
@class MyClassB; // 前向声明@interface MyClassA : NSObject
@property (nonatomic, strong) MyClassB *objectB;
- (void)useMyClassB;
@end// MyClassA.m
#import "MyClassA.h"
#import "MyClassB.h"@implementation MyClassA
- (void)useMyClassB {[self.objectB doSomething];
}
@end
- 前向声明的好处:
MyClassA.h中只有前向声明,编译器不需要在编译MyClassA时处理MyClassB的实现。
任何对MyClassA.h的修改都不会影响MyClassB,从而减少不必要的重新编译。 - 减少编译时间:
编译MyClassA.m时,编译器才处理MyClassB.h。
如果MyClassA.h包含了MyClassB.h,任何对MyClassB.h的修改都会触发重新编译MyClassA及其依赖的文件。
@import
与#import
引入差不多,但是@import
只能引入苹果自己的框架
@import UIKit; 等价于==> #import <UIKit/UIKit.h>
@import UIKit.UIView; 等价于==> #import <UIKit/UIView.h>
以为在实际项目中会使用很多自定义文件与第三方框架,所以统一使用#import
总结
在.h文件中能使用@class尽量使用,而不是#import,#import尽量延后导入,能不使用尽量不使用,可以提高编译效率