iOS学习笔记7 - 前置声明(Forward Declaration),@class与#import
2013-06-04 18:02
393 查看
C#写多了都忘记有前置声明(Forward Declaration)这么回事了,看到@class的时候楞了半天。今天就写这个主题吧。
1. 为什么需要前置声明
前置声明有助于避免循环依赖。像:
这样声明无法编译,因为会遇到先有鸡还是先有蛋的问题。
这时候就需要加一个前置声明:
@class告知编译器,在某个地方有叫这样名字的一个类存在。
2. @class vs. #import
从语法上,使用前置声明和使用#import都能编译通过与运行成功。
那么,这两者分别适用什么场合?
根据http://stackoverflow.com/questions/322597/class-vs-import,
如果你看到警告:
warning: receiver 'myCoolClass' is a forward class and corresponding @interface may not exist
就需要import这个文件了。不过可以不是直接在.h(头文件)里import,而是在.m(implementation文件)里import,在头文件里使用@class声明。
@class通常可以使你不用过早地import。如果编译器看到了一行语法:
@class myCoolClass,它就知道了自己可能马上会看到类似如下的代码:
于是它会为这个类保留一个指针的空间,然后忙其他的去了。
不过如果你需要创建或访问myObject的成员,那么仅仅一个类指针就不够了。你需要让编译器知道这些成员到底是什么。这时候就需要#import "myCoolClass.h"了。
有人简单列了三条规则。由于水平不够,翻译的话可能会导致歧义,我直接放原文:
Only #import the super class, and adopted protocols, in header files.
#import all classes, and protocols, you send messages to in implementation.
Forward declarations for everything else.
在http://stackoverflow.com/questions/6076207/objective-c-forward-declarations-vs-imports
有人提到过,根据他的经验,用#import不慎,有可能会让编译器多编译N多代码(他用了million这个数量级)。只要有一个头文件被稍微修改,所有import的类都需要重新编译,于是拖长了编译时间。
3. 为什么C#不需要前置声明?
我个人Google了一下,没有找到相关的解释。看起来几乎没人对C#为什么没有前置声明感兴趣。。。
关于这个问题我和朋友Zero讨论了一下,他的意见如下:
“C# compiler能够多遍扫描源代码所以不需要任何前置声明。理论上C++ compiler也可以,不过事实上C++ compiler没有这么做而已。”
当然C#也会有循环依赖。这种时候可以用依赖注入(控制反转)来消除,具体可以参见如下:
http://stackoverflow.com/questions/3955465/circular-class-reference-problem
1. 为什么需要前置声明
前置声明有助于避免循环依赖。像:
interface A:NSObject - (B*)calculateMyBNess; @end @interface B:NSObject - (A*)calculateMyANess; @end
这样声明无法编译,因为会遇到先有鸡还是先有蛋的问题。
这时候就需要加一个前置声明:
@class B;
@interface A:NSObject - (B*)calculateMyBNess; @end @interface B:NSObject - (A*)calculateMyANess; @end
@class告知编译器,在某个地方有叫这样名字的一个类存在。
2. @class vs. #import
从语法上,使用前置声明和使用#import都能编译通过与运行成功。
那么,这两者分别适用什么场合?
根据http://stackoverflow.com/questions/322597/class-vs-import,
如果你看到警告:
warning: receiver 'myCoolClass' is a forward class and corresponding @interface may not exist
就需要import这个文件了。不过可以不是直接在.h(头文件)里import,而是在.m(implementation文件)里import,在头文件里使用@class声明。
@class通常可以使你不用过早地import。如果编译器看到了一行语法:
@class myCoolClass,它就知道了自己可能马上会看到类似如下的代码:
myCoolClass *myObject;
于是它会为这个类保留一个指针的空间,然后忙其他的去了。
不过如果你需要创建或访问myObject的成员,那么仅仅一个类指针就不够了。你需要让编译器知道这些成员到底是什么。这时候就需要#import "myCoolClass.h"了。
有人简单列了三条规则。由于水平不够,翻译的话可能会导致歧义,我直接放原文:
Only #import the super class, and adopted protocols, in header files.
#import all classes, and protocols, you send messages to in implementation.
Forward declarations for everything else.
在http://stackoverflow.com/questions/6076207/objective-c-forward-declarations-vs-imports
有人提到过,根据他的经验,用#import不慎,有可能会让编译器多编译N多代码(他用了million这个数量级)。只要有一个头文件被稍微修改,所有import的类都需要重新编译,于是拖长了编译时间。
3. 为什么C#不需要前置声明?
我个人Google了一下,没有找到相关的解释。看起来几乎没人对C#为什么没有前置声明感兴趣。。。
关于这个问题我和朋友Zero讨论了一下,他的意见如下:
“C# compiler能够多遍扫描源代码所以不需要任何前置声明。理论上C++ compiler也可以,不过事实上C++ compiler没有这么做而已。”
当然C#也会有循环依赖。这种时候可以用依赖注入(控制反转)来消除,具体可以参见如下:
http://stackoverflow.com/questions/3955465/circular-class-reference-problem
相关文章推荐
- iOS学习——@class和#import的区别
- ios学习笔记之类声明(接口)
- IOS学习第四篇——@class 和 #import的区别
- IOS学习笔记38--@class #import辨析 #include
- ios 学习笔记4 isKindOfClass 的作用
- 黑马程序员-IOS学习笔记 OC @class的使用 解决循环引入
- iOS笔记--oc语法3 (#include和#import的区别、#import和@class的区别)
- iOS开发21-OC学习- #include、#import和@class,解决#import死循环
- IOS学习笔记38--@class #import辨析 #include
- IOS学习笔记38--@class #import辨析 #include
- ios学习笔记:利用sizeclass匹配不同设备
- iOS开发者的Java学习笔记
- 【iOS学习笔记】c语言问题
- ios学习笔记(六)使用UIScrollView嵌套UIView子类
- 「学习笔记——Python」Google's Python Class 学习笔记
- iOS学习笔记——iOS高级控件
- IOS学习笔记06---C语言函数
- IOS学习笔记——iOS组件之UIScrollView详解
- IOS学习笔记-Category与Extension
- iOS Cocoa Touch学习笔记1