免费开源的iOS开发学习平台

OC预处理:3-文件引用#include/#import/@class

#include

#include 预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。标准C编译器至少支持八重嵌套包含,但是在一个文件中写两个 一样的#include “类名.h”会报错,编译器会认为对同一个文件重复的引用了。

在程序中包含头文件有两种格式:
#include <类名.h>
#include “类名.h”

第一种方法是用尖括号把头文件括起来。这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。第二种方法是用双引号把头文件括起来。这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。

采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有头文件。采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件。

#import

#import 大部分功能和 #include 是一样的,但是他解决了重复引用的问题,我们在引用文件的时候不用再去自己处理重复引用的错误了。

@class

使用@class指令,也可以引入一个类,在声明中与#import的功能类似。但使用@clas指令提高了效率,因为编译器不需要引入和处理整个引入的类。如果需要用到引入类中的属性和方法,使用@class是不够的,必须要使用#import。
如下面例子所示,创建一个新的类ClassC,分别用#import和@class引入两个其他的类ClassA和ClassB。在ClassC.h声明文件中,添加两个属性classA和classB,此时用#import和@class没有区别。

#import <Foundation/Foundation.h>
#import "ClassA.h"
@class ClassB;
@interface ClassC : NSObject
@property (nonatomic,strong) ClassA *classA;
@property (nonatomic,strong) ClassB *classB;
@end

在ClassC.m文件中,新增一个方法print,在该方法中,打印classA和classB对象中的属性,就可以看到用#import和@class的区别。使用@class是不可以引用类中定义的属性和方法的,而使用#import则可以。

#import "ClassC.h"
@implementation ClassC
-(void) print {
    NSLog(@"%@", self.classA.webSite);
    NSLog(@"%s", self.classB.name); //报错
}
@end

报错提示信息如下:

示例代码

https://github.com/99ios/6.3.2