前向声明和头文件有问题

时间:2013-01-07 17:43:44

标签: objective-c header-files forward-declaration

为了缩短构建时间并保持我的代码尽可能简洁,我一直在我的头文件中使用前向声明并将#import语句放在我的实现文件中。到目前为止,这一直很好,但是我遇到了一个问题。假设我有一个类MyClass,它返回类Widget的对象,例如:

@interface MyClass : NSObject
-(Widget*)widgetWithName:(NSString*)name;
@end

假设Widget有方法-(void)arbitraryMethod;

现在,假设我正在实现一个导入MyClass.h的类,实例化MyClass对象,执行widgetWithName:,然后尝试将arbitraryMethod消息发送给返回的Widget,我收到错误receiver type "Widget" for instance message is a forward declaration。因此,我必须继续导入Widget.h头文件以修复错误。

当然,当我返回Foundation课程时,这绝不是问题,因为#import <Foundation/Foundation.h>位于Prefix.pch

最佳做法是什么?我的直觉是,如果我返回一个类或使用该类作为公共方法中的参数,则头文件应该包含在我的头文件中。否则,如果我有一个在面向公众的方法中使用了十个不同的非基础类的类,那么每次他们想要使用该方法时,我的用户都必须追捕并将新的头文件导入到他们的项目中。

这是正确的还是有更好的模式可供使用?

2 个答案:

答案 0 :(得分:3)

您不能跳过将标题中的标题导入到您没有为返回类型中使用的类导入标题的位置。在这种情况下,我假设您在@class Widget;的标题中使用了MyClass。您不能在类型仅使用@class向前声明的对象上调用方法,因为我记得bbum saying,编译器没有必要的数据。除了通过使用@class“存在”之外,你基本上没有告诉过这个类,它通常不仅仅用于破坏循环引用。我认为尽可能干净,但是为实现中内部使用的类导入标题,但正如您所说,导入标题中公共方法中用作返回和参数类型的任何类的标题。

答案 1 :(得分:0)

你正在做的一切。

是的,您需要在其他类实现文件中导入MyClass.hWidget.h。您需要导入Widget.h,因为您实际上正在使用 Widget类 - 通过调用类型Widget *的对象指针上的方法。在实现文件中,您应该为实际使用的每个类导入标头;你永远不必关心标题MyClass.h导入或不导入的内容(它应该像你一样尽可能少地导入)。