#import与@class的区别
转自:http://www.cnblogs.com/jqyp/archive/2012/01/13/2321707.html
1.import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你。
2.在头文件中, 一般只需要知道被引用的类的名称就可以了。 不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称。 而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。
3.在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。
4.如果有循环依赖关系,如:A–>B, B–>A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。
所以,一般来说,@class是放在interface中的,只是为了在interface中引用这个类,把这个类作为一个类型来用的。 在实现这个接口的实现类中,如果需要引用这个类的实体变量或者方法之类的,还是需要import在@class中声明的类进来.
举个例子说明一下。
在ClassA.h中
#import ClassB.h 相当于#include整个.h头文件。如果有很多.m文件#import ClassA.h,那么编译的时候这些文件也会#import ClassB.h增加了没必要的#import,浪费编译时间。在大型软件中,减少.h文件中的include是非常重要的。
如果
只是 ClassB 那就没有include ClassB.h。仅需要在需要用到ClassB的.m文件中 #import ClassB.h
那么什么时候可以用呢?
如果ClassA.h中仅需要声明一个ClassB的指针,那么就可以在ClassA.h中声明
@ClassB
...
ClassB *pointer;
假设,有两个类:ClassA和ClassB,两个之间相互使用到,即构成了circular dependency(循环依赖)。如果在头文件里面只用#import把对方的头文件包含进来(构成circular inclusions,循环包含),则编译器会报错:
Expected specifier-qualifier-list before ‘ClassA’
或者
Expected specifier-qualifier-list before ‘ClassB’
为了避免循环包含,在ClassA.h文件里面用@class classB把classB包含进来,同样,在ClassB.h文件里面用@class ClassA把ClassA包含进来。@class指令只是告诉编译器,这是个类,保留个空间来存放指针就可以了。
接下来,很可能在ClassA.m和ClassB.m中会有访问包含进来对象的成员的情况,这时必须让编译器知道更多信息,比如那个类有些什么方法可以调用,就必须用#import,再次把用到的类包含进来,告诉编译器所需要的额外信息。
否则,编译器会警告:
warning: receiver ‘ClassA’ is a forward class and corresponding @interface may not exist
还有另一种情况,使用有Categories的类,要在.h头文件里用#import把Categories包含进来。
总之,使用原则是:
头文件里面只#import超类 消息文件里面#import需要发消息过去的类 其他地方就用@class转向声明
#import与@class的区别的更多相关文章
- @import和link的区别
@import和link的区别 1.link语法结构 <link href="CSSurl路径" rel="stylesheet" type=&qu ...
- #import和#include的区别 关键字@class的作用
一.#import和#include的区别当我们在代码中使用两次#include的时候会报错:因为#include相当于拷贝头文件中的声明内容,所以会报重复定义的错误但是使用两次#import的话,不 ...
- export,import ,export default区别
export,import ,export default区别 一.export,import ,export default ES6模块主要有两个功能:export和import export用于对 ...
- 1.ARC下是否有内存溢出等问题 2.@property参数 3.#import和@class的区别
1.ARC下是否有内存溢出等问题? 答案:必须要担心啊,ARC也不是万能的.答案:必须要担心啊,ARC也不是万能的.这里主要是涉及到集合类的数据类型 比如数组,我们定义了一个可变数组muarr1, ...
- 少勇 #import和@class的区别
#import与@class的区别1.import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告 ...
- css中import与link用法区别
方式:引入CSS的方法有两种,一种是@import,一种是link @import url('地址');//注意,这种方式可以放在页面也可以放在css文件中<link href="地址 ...
- 调用css时,用link 和 @import url 有什么区别
加载css link与@import的区别: 其实 link 与 @import 在显示效果上还是有很大区别的,基本上来看 link 的加在会在页面显示之前全部加在完全,而 @import 会是读取完 ...
- ios import和@class的区别
二者的区别在于: 1.import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你. 2.在头 ...
- css文件加载:@import和link的区别
刚看了一个百度试题:请简述CSS加载方式link和@import的区别? 平时一般都用link,也知道css的加载方式,但还真的没有仔细研究过其之间的差别,查了一些资料,大致总结如下: @impot使 ...
- iOS学习——@class和#import、#include的区别
在iOS开发过程中,我们在一些源码中经常会看到导包的时候有的用#import进行导包,但是有的的时候也会看到用@class进行导包,那么这两种方式有什么区别呢? 一 @class和#import的主要 ...
随机推荐
- linq性能剖析
Orcas(VS2008&Framework3.5)给我们带来了很多令人兴奋的新特性,尤其是LINQ的引进,可以说方便了一大批开发 人员和框架设计人员.过去,当我们使用O/RMapping的一 ...
- 【Python学习笔记】字典操作
字典dict是Python中唯一内置的映射类型,由键值对组成,字典是无序的.字典的键必须是不变对象,如字符串.数字.元组等,而包含可变对象的列表.字典和元组则不能作为键.这里可变和不可变的意思是指这个 ...
- MySql 5.6 慢查询
网上都巨坑 最后在官网找到了开启方法 原来是配置文件改了 Updated example for 2015 MySQL 5.6: slow_query_log = 1slow_query_log_fi ...
- dom 筛选器
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 记录一个 关于 python 普通方法,静态方法和类方法 的介绍。@classmethod @staticmethod
上班时间 只贴看到最厉害的答案 回头总结 http://stackoverflow.com/questions/12179271/python-classmethod-and-staticmethod ...
- 一些推荐的spark/hadoop课程
为了分享给你们,也为自己. 感谢下面的老师们! 1.王家林DT大数据梦工厂的大数据IMF传奇行动课程 总的目录是: 第一阶段:Linux和Java零基础企业级实战 第二阶段:Hadoop和Hive零基 ...
- ASP.NET自定义控件入门Demo
最近看了MSDN关于自定义控件的介绍,根据官方的文档,自己学着做了一个简单的Demo给需要的朋友参考. ASP.NET 源生的TextBox是不带Label标签的,这里我要实现的是创建一个带Label ...
- Azure中国版 制作镜像 捕捉镜像
因为项目需要需要部署多台功能一样的服务器,简单来说是多台nginx服务器.如果按照原始的做法,是新建vm,然后一台台部署相关服务. 现在Azrue已经可以通过捕获镜像的方式创建vm镜像模板,然后按照创 ...
- Java反射机制(Class类的使用)
1:通过无参构造实例化对象 package cn.itcast; /* * 通过无参构造实例化对象 * 通过Class类本身实例化对象,使用newInstance方法 * 需要注意的是:实例化类中存在 ...
- KMP(http://acm.hdu.edu.cn/showproblem.php?pid=1711)
http://acm.hdu.edu.cn/showproblem.php?pid=1711 #include<stdio.h> #include<math.h> #inclu ...