【问题标题】:What's the difference between #import and @class, and when should I use one over the other?#import 和@class 之间有什么区别,什么时候应该使用其中一个?
【发布时间】:2008-10-31 10:21:04
【问题描述】:

在过去一个月左右的时间里,我一直在自学 Objective-C(我是一名 Java 负责人),现在我的大部分内容都已经掌握了。目前让我感到困惑的一件事是:通过@class 导入类与执行#import 有什么区别?

是一种比另一种更好,还是在某些情况下我需要使用一种而不是另一种?到目前为止,我一直只使用#import。

【问题讨论】:

    标签: objective-c cocoa-touch


    【解决方案1】:

    #import 将有问题的整个头文件带入当前文件;还包括该文件#imports 的任何文件。另一方面,@class(当在一行上单独使用某些类名时)只是告诉编译器“嘿,你很快就会看到一个新的标记;它是一个类,所以这样对待它)。

    当您有“循环包含”的潜力时,这非常有用;即,Object1.h 引用Object2,Object2.h 引用Object1。如果您将#importboth 文件放入另一个文件中,编译器会在尝试#import Object1.h 时感到困惑,查看它并看到Object2.h;它尝试#importObject2.h,并看到Object1.h等。

    另一方面,如果这些文件中的每一个都有@class Object1;@class Object2;,那么就没有循环引用。请务必将所需的标头实际#import 放入您的实现 (.m) 文件中。

    【讨论】:

    • Ben,Ben,您不必在 Stack Overflow 上回答每个 Cocoa 问题。你会筋疲力尽的!
    【解决方案2】:

    @class 称为前向声明。您基本上是在告诉编译器该类存在,但与该类无关。因此,它不知道它的超类以及它声明的方法之类的东西。

    作为一般规则,如果可能,请在 .h 中使用 @class,在 .m 中使用 #import。就像 Louis 说的,这将有助于加快编译时间。不过,有时您需要在标题中 #import 一个类。我现在能想到的案例有:

    • 您正在继承另一个类
    • 您正在实施一个协议

    在这些情况下,您必须 #import 声明类或协议的头文件,因为编译器需要知道其父类和实现协议的完整类层次结构。

    FWIW,你也可以转发声明协议,只要你不实现它们:

    @protocol SomeProtocol;
    
    @interface ...
    
    - (id<SomeProtocol>)someMethod;
    
    @end
    

    【讨论】:

      【解决方案3】:

      您要记住的另一件事是#imports 会减慢您的编译时间,因为这意味着编译器需要提取并处理更多的头文件。这主要被预编译头文件的使用所掩盖,但我偶尔会收到一些项目,这些项目会交叉导入每个头文件,而不是在适当的地方使用@class,修复它们可以提高编译时间。系统以一种微妙的方式强化了这样一个事实,即如果你只使用你真正需要的东西,事情就会变得更快。

      作为一般规则,我总是在我的头文件中使用@class 声明,并且只使用#import 超类。这符合 Ben 的建议,但我认为值得注意的是,即使您不担心循环引用,如果可以的话,最好在头文件中限制 #imports。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-08
        • 2010-12-24
        • 1970-01-01
        相关资源
        最近更新 更多