【问题标题】:Why @class instead of #import for ViewController in AppDelegate.h?为什么在 AppDelegate.h 中为 ViewController 使用 @class 而不是 #import?
【发布时间】:2012-01-26 10:06:08
【问题描述】:

我在 Objective C 中有一个基本的最佳实践问题。我了解 @class#import 之间的区别,但我不明白为什么默认的 Apple Xcode 模板会这样做:

AppDelegate.h:

@class ViewController;

.m:

#import "ViewController.h

当您可以将后者 #import 放在 .h 中并将 ViewController 完全从 .m 中删除时,从而简化了 1 行代码。

当然,节省 1 行代码不是问题,我只是好奇为什么会这样?

【问题讨论】:

    标签: objective-c uiviewcontroller


    【解决方案1】:

    @class ViewController; 行是前向声明,因此编译器知道名称 ViewController 的含义。关键是尽量在头文件中少写#import,以加快编译速度。

    想象一个文件a.h 执行#import "b.h"。现在每个导入a.h 的文件都会自动导入b.h,这增加了编译器必须做的工作量。通过使用前向声明,通常可以避免此类额外的导入,从而避免编译器的额外工作。

    项目越大,类层次结构和依赖关系越复杂,#imports 就越容易成为问题。因此,最好养成尽可能使用前向声明的习惯。

    编辑: 在 cmets 之后,另一个重要的用例浮出水面:解决循环依赖关系。例如,如果类 A 想要引用类 B,反之亦然,则必须先定义一个类。但是因为他们需要了解对方,所以我们有一个悖论。是这样解决的:

    // Tell the compiler: B will be a class type.
    @class B;
    
    // Now we can define A, the compiler has enough
    // information to know what B means.
    @interface A : NSObject {
        B *b;
    }
    @end
    
    // Since A is now defined, we can define B.
    // Cycle is resolved.
    @interface B : NSObject {
        A *a;
    }
    @end
    

    【讨论】:

    • 除了编译时间,实际的程序性能会受到这两种方法的影响吗?
    • 伟大而简单的解释@darkdust
    • 正如dreamlax所说,运行时不受此影响。这仅在编译时起作用,以便编译器对名称(类型)应该是什么有一个粗略的了解。在您想要使用该类的实例的.m 文件中,您需要执行#import,编译器会了解所有详细信息,例如方法名称和其他符号。
    • 是的,但RootViewController.h 长什么样子?
    • Xcode 一次只将.m 文件传递​​给编译器。然后一个.m 文件导入它需要的所有.h 文件。这就是为什么您可以设置.m 文件的Target Membership,但不能设置.h 文件的原因。编译器不会将.m.h 文件视为对,它不知道(也不关心)两者之间的任何关系。事实上,你可以随意命名.h 文件,扩展名.h 只是一个约定。
    【解决方案2】:

    前向类声明:

    @class ClassName;
    

    用于不需要特定属性、属性或方法信息的头文件中。

    这允许头文件的#import#include 没有#importing ClassName.h 带来的任何开销。

    【讨论】:

      【解决方案3】:

      #import 用于我们或 Apple xcode 预定义的类,但 @class 是我们在定义它之前使用的(它是类的前向声明),在我们的父类/或上一个类中

      所以它告诉编译器在我们的项目中有一个具有此名称的类,因此编译器不会为该类名称添加错误。

      【讨论】:

      • 格式可以显着改善。
      猜你喜欢
      • 2018-01-04
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多