iOS基础 -- #imoprt、#include、@class

来源:互联网 发布:买家虚拟物品淘宝介入 编辑:程序博客网 时间:2024/06/07 03:39

这边这个人CSDN写了个面试的专栏吧,给个链接:
http://blog.csdn.net/column/details/iosinvterview.html

#import、#include、@class

#include

#include是C语言中就有的东西,也能在objective-c中使用(objective-c兼容所有的c代码)。

#include做的事情就是将对应文件的内容全部都贴过来,比如:
a.h头文件中内容是这样的:

typedef int my_number; 

b.h头文件中是这样的:

#include "a.h"#include "a.h"

那么处理器在编译之前就会将b.h的代码展开成下面的样子:

typedef int my_number; typedef int my_number; 

这样之后,编译器就会报错,c中是不允许同一个变量名声明两次的。
在项目中一个文件是经常会被各类文件include的,比如b文件A和B都引用了文件C。然后文件D引用了文件A和文件B的话,那就会导致文件D引用了两次文件C,编译器就会报重复引用的错。
所以为了避免这个,在C语言中经常会用到一个叫#include gurad的东西,其实就是用一个宏定义把代码包起来,当第二次碰到这块代码时,因为这个宏已经有了,就不会再定义就直接跳过了(使用这种方法要保证各个文件中的宏的名称是唯一的):

 #ifndef _a_h_included_ #define _a_h_included_ typedef int my_number; #endif

#include<>与#include”“区别

#incldue的使用有两种类型,一种是尖括号<>,一种是引号”“。那么两种有什么区别呢:
- #include<>:用于对系统自带的头文件的引用,编译器会在系统文件目录下查找该文件
- #include”“:用户自定义的文件用双引号引用,编译器会优先查找用户目录,然后到安装目录中查找,最后在系统文件目录中查找。

#import

在Objective-C中新增了#import这样一个文件导入命令,算是一个增强型的#include吧。
#import命令所做的事情大部分是跟#include一样的,但是它解决了可能会出现的重复引用的问题。
当第一次遇到#import导入的文件时,才会将内容替代进来,之后再遇到的话就会直接忽视。

#import<>和#import”“的区别

与include类似,#import命令也有<>和”“两种用法:
- #import<>:与include<>类似,编译器会在系统文件目录下查找使用<>方式引用的文件,如果引用自定义的放在项目目录下的文件,用这种方式是会报错的!
- #import”“:与include”“类似,编译器会优先在项目目录(具体该说是哪个目录我也说不太来)下查找,随后才会去安装目录(iOS线项目有没有这个东西呀)、最后再到系统目录中寻找。也就是一个目录查找优先级的问题,所以系统框架文件如果使用引号也是不会报错的。

下面是来自stackoverflow关于这个问题的答案:
https://stackoverflow.com/questions/1044360/import-using-angle-brackets-and-quote-marks

Objective-C has this in common with C/C++; the quoted form is for “local” includes of files (you need to specify the relative path from the current file, e.g. #include “headers/my_header.h”), while the angle-bracket form is for “global” includes – those found somewhere on the include path passed to the compiler (e.g. #include 《math.h>).

So to have your own headers use < > not ” ” you need to pass either the relative or the absolute path for your header directory to the compiler. See “How to add a global include path for Xcode” for info on how to do that in Xcode.

–补充–2017年10月20日
下面的话摘自《精通Objective-C》:

这两种形式之间唯一区别在于编译器寻找文件的方式。
- 当使用双引号(”“)封装头文件的名称时,编译器会先从存储源文件的目录中搜索被包含的头文件。如果没有找到,编译器会在默认目录中搜索头文件,默认目录是与预先配置的用于搜索系统标准头文件的目录。
- 当使用尖括号(<>)封装头文件的名称时,编译器会在默认目录中搜索被包含的头文件。

@class

@class是一个 forward declaration(前置声明),它的作用就是告诉编译器,用@class声明的这个东西是一个类。其他类的属性方法这些是都不知道的,而且我也不需要知道(因为在.h文件中我并不要使用具体的内容)。
一般是在.h文件中使用@class声明,免得要引入那么多东西。在.m文件中需要用到具体的属性、方法的时候再用#import命令在.m文件中导入。

@class可以用于解决“循环引用”的问题。比如在A中#import了B,然后又在B中#import了A。这个时候代码不会报错,但是会在编译期报类似这样的错误:Unknown type name ‘A’。这就是因为两各类之间的循环引用造成的,需要我们在其中一个类中使用@class。

另外,在编译效率方面考虑的话,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。