【问题标题】:Objective-C forward declaration vs #import in model hierarchy [closed]模型层次结构中的Objective-C前向声明与#import [关闭]
【发布时间】:2014-03-05 13:23:32
【问题描述】:

我知道在 stackoverflow 上有很多关于 @class 前向声明和 #imports 之间差异的问题 - 我明白这主要是编译器优化和减少循环导入问题。

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

// 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 资深人士对此的看法。

【问题讨论】:

  • @class vs. #import 的可能重复项
  • @Avt 谢谢你的链接。我在搜索 StackOverflow.com 时确实发现了这个问题(以及更多问题),但这并不是我要问的。我很好奇在深层模型层次结构中使用#imports 来防止在使用该模型的所有控制器类中出现数十行导入是否是一种好习惯。谢谢。

标签: objective-c cocoa import forward-declaration


【解决方案1】:

我总是像苹果那样做:我“从不”级联导入,但我通常有一个“包装器 h 文件”......

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

【讨论】:

  • 可以说是伞头
  • 认为,但找不到支持我的视频,制作这些预编译头文件 (.pch) 也会在编译时提高性能。
  • 那些根本不是 PCH。你不应该只依赖 pchs。虽然它们提高了性能,但稍后将它们添加到 pch 可能是有意义的
  • pchs 确实提高了性能,但使整个事情变得更加脆弱。 google 一下 pchs 的优点/缺点
【解决方案2】:

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

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

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

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

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

【讨论】:

    【解决方案3】:

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

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

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

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

    如果您将使用#import,任何导入 MyNetworkClass.h 的网络层类也会知道 MyProgressView。有悖于责任共担!所以在这种情况下@class会更好。

    【讨论】:

      猜你喜欢
      • 2013-04-02
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 2017-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多