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

3
我一直遵循以下规则:
在类的头文件中使用 @MyClassName
在实现文件中使用 #import "MyClassName" 现在我决定对一个视图控制器进行子类化。如果我重写一个方法,那么我会得到以下消息:
接收器“ MyClassName”用于类消息是一个前向声明。
为了克服这个问题,我需要将 #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

如果我在子类中覆盖一个方法并尝试使用一个Organisation对象,它会给我报错,就像我上面所说的那样。因此,我需要将#import "Organisation.h"添加到基类头文件中,或者将#import "Organisation.h"复制到子类的实现文件中。这两种方法都似乎不正确。
非常感谢。
2个回答

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语句时,你不应该考虑“复制”这个语句。当你在LongCallDetailViewController头文件中使用前置声明@class Organisation时,在LongCallDetailViewController源文件中,你将有一个#import "Organisation.h"。如果你还需要在LongCallSubclassViewController类中访问这个对象的属性和选择器,你需要在LongCallSubclassViewController实现文件中#import "Organisation.h"。记住:实现文件并不知道彼此的内容,它们只知道头文件的内容。

我已经编辑了我的问题,以更好地说明我面临的问题。谢谢。 - pls
非常感谢您更新您的答案。我希望有一种方法可以避免重复使用 #import :-)。您的答案已经为我澄清了事情。 - pls
如果你在LongCallDetailViewController的头文件中放置了#import "Organisation.h",你就不必再输入一遍了。我不确定在这种情况下我对“最佳实践”的立场是什么;它为潜在的子类提供了帮助,但也可能导致导入循环(如果你对导入非常粗心)。 - Ian MacDonald

0

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

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

当您:

  • 子类化一个类 - 导入您的类的其他类需要了解该类支持的所有方法。
  • 实现协议 - 与上述原因相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接