Objective-C前向声明vs模型层次结构中的#import

时间:2014-03-05 13:23:32

标签: objective-c cocoa import forward-declaration

我知道有关@class前向声明和#imports之间差异的stackoverflow有很多问题 - 而且我确实理解它主要是编译器优化并减少循环导入问题。

我的问题更多是关于下列情况下的编码风格,例如我的模型结构如下所示。

// Classroom.h
@class Teacher;

@interface ClassRoom : NSObject

@property (nonatomic, strong) Teacher *teacher;
- (NSArray *)students;

@end



// Teacher.h
@interface Teacher : NSObject

@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;

@end

现在,当我在另一个类中使用它时,如果我想通过

访问firstName属性,我需要导入Teacher.h和ClassRoom.h
teacherObject.firstName

然而,如果我使用#import Teacher.h而不是@class Teacher;我只需要导入#Teacher。

所以我的主要问题是,如果这是一个使用导入而不是前向声明的合理场合?我在我的项目中使用的实际模型结构比这复杂得多,我经常需要在我的实现文件的开头(在控制器中)导入5-10个不同的模型类。虽然这不会伤害任何东西,但它确实会令人沮丧,并使源代码更长。我很想听到Objective-C老兵的意见。

3 个答案:

答案 0 :(得分:2)

我总是像苹果那样做:我从来没有'级联进口,但我通常有一个'包装文件'......

就像我有FeatFooA.h时的FeatFooB.h FeatFooC.h一样 我也有一个AllFeaturesFoo.h

答案 1 :(得分:1)

我个人觉得在#import文件中明确显示与.m的依赖关系很好/很方便。

但是,应用程序通用的文件(可以在(几乎)所有模块中使用)构成例外。

  1. 在这种情况下,您可以在#import所有这些通用标头中使用一个公共标头;然后在每个模块中#import这个单个标题。

  2. 或者,您可以将此通用#import列表放在AppName-Prefix.pch文件中。 (或者甚至做一个#import公共标题(见上文)。)在这种情况下,您不必在模块中#import进行任何操作。但我个人不喜欢隐藏/隐含的东西;所以我宁愿选择第一个选项。

  3. 然后关于您的示例:创建School.h可能是有意义的,这将是唯一需要的标头。如果事情彼此依赖,因为它是某个概念的一部分(在这个例子中就是学校),保持界面简单是件好事。我知道这听起来很模糊,但我希望你明白这一点。

答案 2 :(得分:0)

据我所知,您的问题是关于代码质量和最佳编码实践。

恕我直言#import更方便,因为您永远不会收到编译错误“Unknown Class”

但有一种情况我不建议使用#import。假设您的应用中有多个图层。让我们说:网络,控制器和视图(GUI)。出于某些原因,您必须从网络层访问GUI类MyProgressView(例如,您使用的是第三方库):

@interface MyNetworkClass : NSObject
@property (strong, nonatomic) MyProgressView *progressView;
@end

如果您将使用#import导入MyNetworkClass.h的任何网络层类,也将了解MyProgressView。这与责任分担相反!所以在这种情况下@class会更好。