gar*_*uan 7 import cocoa header objective-c
我不知道为什么,但有时我设法修复了一些编译错误,最值得注意的是
error expected specifier-qualifier-list before 'someClass'
Run Code Online (Sandbox Code Playgroud)
#import "someClass.h"从.h文件移动到.m文件.这也解决了我遇到的其他一些与标题有关的问题(从我的观点来看神秘).
一些粗略的谷歌搜索已经出现了答案"从不在头文件中导入标题",这就是建议停止的地方.
要么我完全做到了,要么我已经从某个地方养成了习惯,但我认为标题是要导入标题的地方.显然不是,但任何人都可以向我解释为什么会这样,以及导入标题的首选方式是什么?
Rob*_*ier 13
约翰给出了很好的建议,但这里有更多关于为什么,为什么和例外的背景.
避免将标头导入标头有两个目的:改进增量构建时间和避免循环依赖.如果导入A.h到B.h和进口B.h到C.h,然后每次你在改变什么时间A.h,你必须重新编译C.m,即使C.m是没有使用任何的定义的东西A.h.这可能导致非常糟糕和不必要的构建流失,特别是如果您有经常更改的标头(在开发的早期阶段很常见).
第一个目标值得称赞,但对于小型项目,谁在乎呢?你有一个四核专业版和一个完整的版本需要几分钟,对吧?但你还是要担心第二个问题:循环依赖.A.h引用类B和B.h引用类A.这实际上可能经常发生,并且可以非常无辜地进入系统.集合对象可能引用它包含的对象的类型,并且对象可能引用集合对象的类型.所需要的只是一个引用,因为某些方法接受或返回该类型.如果您有导入其他标题的标题,则发生这种情况的可能性很快就会达到统一.你结束了递归导入,编译时错误可能令人费解."我知道 typdef是定义的!它就在那里!它是进口的!" 但是,当您导入此标头时,它尚未解析.这就是导致您的错误的原因.
出于这个原因,即使你不关心构建时间(尽管你应该),也要避免将头文件导入头文件......除了....
您必须导入一些标头.你的超级课程当然.定义@protocol您实现或typedef使用的文件.所以,是的,你必须包括那些.
那么系统头呢?好吧,它们永远不会导致流失,显然它们不会导致递归导入,所以它们很好.我不鼓励人们@class在系统头文件中使用前向声明.它为您的标题用户创建了额外的工作,没有任何价值.为了获得良好的标题卫生,请记住将系统标题括在<尖括号>中,将标题括在"引号"中.
所以这不是一个简单的问题,但简单的规则是:避免在编译器允许的任何时候将用户头导入其他用户头.
Joh*_*lla 10
除非您继承自包含的类,否则不应在标题中包含标题.如果需要将对象包含为接口变量,则应该使用该@class指令; 这将告诉编译器标识符引用一个类.
而是仅在实现文件中导入标头.编译器将知道您的实例变量是指向对象的指针,但在解析标头时它不知道对象的详细信息.它需要知道的是它是一个类.然后,编译器可以在解析实现文件时查看类的方法; 此时,它确实需要该类,以验证它是否响应您正在发送的消息.
更新:我打算更新我的回答以回应一些后来的问题,但Rob Napier有一个很好的跟进.
| 归档时间: |
|
| 查看次数: |
979 次 |
| 最近记录: |