子类化视图控制器:前向声明

时间:2014-10-07 15:54:52

标签: ios objective-c subclassing

我一直遵循以下规则:

类的头文件中的@MyClassName

&安培;&安培;

#import" MyClassName"在实施中

我现在决定将其中一个视图控制器子类化。如果我覆盖一个方法,那么我收到以下消息:

接收者' MyClassName' for class message是一个前瞻声明

为了解决这个问题,我需要将#import放入头文件中,这似乎不符合我认为的最佳实践。

有人可以解释我是否误解了@class的使用?

或者如果我是正确的东西,有人可以解释一下你需要打破最佳实践并在子类化时在头文件中使用#import吗?

非常感谢。

修改

感谢您的回答。我想我需要添加更多细节来澄清我的情况,并希望我的理解。这是我的基类的标题:

#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"

@class Organisation;

@interface LongCallDetailViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

在我的实践中,我有

#import "Organisation.h"

我的子类标题包含以下内容:

#import "LongCallDetailViewController.h"

@interface LongCallSubclassViewController : LongCallDetailViewController

@end

如果我覆盖子类中的方法并尝试使用Organization对象,它会给我错误,如上所述。因此我要么添加#import&#34; Organisation.h&#34;进入基类标题或复制#import&#34; Organisation.h&#34;进入子类实现文件。这两件事对我来说都是错误的。

非常感谢。

2 个答案:

答案 0 :(得分:3)

在头文件中,您应该为您子类的任何类导入其他头文件。您不需要为刚引用但未进行子类化的类导入头文件。例如,头文件可能如下所示:

#import "MySuperClass.h"

@class MyObjectType;

@interface MySubClass : MySuperClass
@property (strong) MyObjectType *value;
@end

修改: 根据您的新编辑,您似乎正在正确编写头文件。当您仅在范围中声明@class时,您将无法访问与该类关联的任何选择器或属性。可以在不打算使用该类类型的选择器或属性的地方声明使用@class,只是传递一个引用(如我上面描述的标题),但是只要你想要要对该对象执行任何其他操作,您需要导入描述@interface的头文件。

在头文件中定义@class MyObjectType时,通常期望#import "MyObjectType.h"出现在关联的源文件中。头文件旨在作为结构声明,而源文件将包含实现。例如,与我上面描述的头文件关联的源文件可能如下所示:

#import "MySubClass.h"

#import "MyObjectType.h"

@implementation MySubClass
- (void)overriddenFunction {
  [self.value anObjectTypeSelector];
}
@end

当它们处于两个不同的范围时,你不应该考虑“复制”一个import语句。当您在@class Organisation标头文件中转发声明LongCallDetailViewController时,您的#import "Organisation.h"源文件中会有LongCallDetailViewController。如果您还需要在LongCallSubclassViewController课程中访问此对象的属性和选择器,则需要在#import "Organisation.h"实施文件中LongCallSubclassViewController。请记住:实现文件不知道彼此的内容;他们只知道头文件的内容。

答案 1 :(得分:0)

#import使用所有公共方法和属性导入类的定义。

@import预先声明类,因此没有关于方法和属性的信息

在以下情况下使用#import:

  • 您是一个类的子类 - 导入您的类的其他类需要知道类支持的所有方法。
  • 您实施协议 - 与上述原因相同。