Xcode中的头文件包含自身没有警告

时间:2014-05-18 20:43:25

标签: ios objective-c xcode objective-c-category

我在iOS项目中包含了一个广泛使用的UIImage类别来处理PDF,并且出现了一些编译错误。这提出了几个问题。

Q1:为什么Xcode(或实际上是LLVM编译器)不会对包含自身的头文件发出任何警告?我不知道这在C或Objective-C中是否具有特殊含义会阻止它被视为拼写错误?在我的例子中,我认为犯了一个错误,而Foundation.h可能是预期的包括:

在类别文件NSString+MD5.h中,我找到了:

#import "NSString+MD5.h"

@interface NSString(MD5)
- (NSString *)MD5; 
@end

相应的.m不包含.h。 (链接是" Here")

Q2:我收到了编译错误,因为我是从一个不包含Foundation框架(适用于iOS的AVCam 3.1)的Apple项目开始的!所以NSString未定义。我对此有点疑惑但是在xcode中与基础框架的链接就像包括它的所有标题一样?我至少会再次发出一些警告?

感谢您对这个可能非常基本的C主题的任何解释。

1 个答案:

答案 0 :(得分:2)

首先,在Objective-C中,我们#import,与#include不同。虽然#include会尝试包含您列出的任何文件,但#import永远不会双重导入任何文件。我想这可以解释为什么.h文件尝试#import本身没有问题。文件导入本身不正确,但因为它是#import,它实际上不会导致任何问题。


至于.m文件没有导入它.h,在这种情况下,它实际上并不需要。出于习惯,总是导入.h文件是一个好主意,Xcode生成的任何文件都会自动执行此操作,但并不总是必要的。仅当.h文件声明了.m必须知道的内容时,才需要它。例如,您打算使用的@property。您已在.h中对其进行了声明,因此它具有公共访问权限,但如果您打算在.m中使用它,.m必须知道@property已定义{1}}。此外,如果您#import编辑了.h .m.m所需的某些文件,而您又不想在.h中再次导入这些文件,您需要导入.m(尽管在.h中导入它们通常会更好。

这里,NSString *只是定义了一个返回md5的方法的存在,并且被称为.h并且不带参数。这意味着导入此md5文件的任何内容都可以调用此方法,Xcode不会抱怨.m方法不存在。相应的.h文件实现的方法恰好与.m定义的方法匹配。如果您删除了md5文件,您的程序几乎肯定会编译得很好......但是当您转到.m被调用的点时,您会遇到无法识别的选择器异常 - - 尽管Xcode没有抱怨它。使用项目中的Foundation.h,此异常不会被触发。该程序在运行时计算出要执行的方法。


最后,至于不包括#import Foundation.h,Xcode创建的每个iOS项目在预编译头文件中都有#import UIKit.h.pch。项目中包含这些导入的任何其他文件只是冗余导入文件,因为它已由#import导入,但由于#include的魔力(vs {{1}它实际上并没有双重导入。

如果您正在处理的.pch中没有这些导入的iOS项目,最好的办法是将它们粘贴在.pch

如果您出于某种原因反对这一点,修复此md5文件的最佳方法是使用以下简单的行:

@import Foundation.NSString;