在Objective-C中将.import语句放在.m而不是.h文件中的理由是什么?
Apple示例将它们捆绑在.m文件中,除非在接口声明(.h)中使用了对象,并且docs声明这是正确的(“在接口文件中,首先导入任何必需的头文件。”)
令我困惑的是.h应该定义实现的接口,所以#import逻辑上会转到.h文件而不是.m。
答案 0 :(得分:11)
如果将所有#import
放在头文件中,则没有两个类可以相互依赖,因为文件无法导入导入它的文件。另一方面,如果将#import
放在实现文件中,问题就会消失。
答案 1 :(得分:8)
在任何源文件中,您只应#import使您的文件对编译有效。请记住,您的标题可能被其他类使用,因此您希望尽可能使它们变得轻量级。这也是为什么最好使用@class来表示除超类之外的类的前向声明。
答案 2 :(得分:4)
如果你的类的接口依赖于另一个类的接口(即它是否是一个子类),那么请包含头部,否则使用@class
向前声明另一个类,并在依赖项中包含该类的接口头class的源文件。
推理很简单;通过仅引用标头中的类而不是导入整个接口,您可以定义相互依赖的类(即彼此依赖的类),否则这样的设置是不可能的,因为会发生递归文件包含(但是Objective-C #import
确保不会发生这种情况。)
答案 3 :(得分:2)
接口通常只是该类可用的方法。一个接口可以具有任意数量的可互换实现。在实现内部而不是在头部内部导入会阻止其他实现导入它可能不需要使用的类。它是关于信息隐藏和保持代码需要知道的基础。
答案 4 :(得分:1)
在Objective-C中将.import语句放在.m而不是.h文件中的理由是什么?
也许在实现中的一个方法中,您已经实例化了一个类型的局部变量,您可能只使用一次或两次,并且您不希望#import
语句混乱您的头文件。或者您可能在标题中使用了@class
作为转发声明,并且您需要使用#import
语句在您的实现中引用该类。
答案 5 :(得分:1)
除了其他所有内容之外,它还可以在编译时获得性能。当您#import
文件时,就像将文件内容粘贴到标题中一样。在编译代码时,编译器需要完成更多工作。
见page about Clang compiler performance。
请注意,在Cocoa.h等标准头文件中,预编译头文件可以解决大部分问题。