我在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主题的任何解释。
答案 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;