为什么在AppDelegate.h中使用@class而不是#import来引用ViewController?

11 浏览
0 Comments

为什么在AppDelegate.h中使用@class而不是#import来引用ViewController?

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

AppDelegate.h:

@class ViewController;

.m:

#import "ViewController.h

你可以只在.h中放置后者的#import,并完全不提及.m中的ViewController,从而简化1行代码。

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

0
0 Comments

为什么在AppDelegate.h中使用@class而不是#import来引用ViewController?

在Objective-C中,我们通常使用#import来引入其他类的头文件,以便可以在当前类中使用这些类。然而,在某些情况下,我们可能需要在一个类中引用另一个类,而不需要真正地导入它的头文件。这种情况下,我们可以使用@class关键字来进行前向声明。

在AppDelegate.h中,我们经常需要引用ViewController类,以便在应用程序的委托中使用它。通常情况下,我们可以使用#import来导入ViewController的头文件。但是,如果我们只是想告诉编译器有一个名为ViewController的类存在于我们的项目中,并不需要实际导入它的头文件,那么我们可以使用@class来进行前向声明。

为什么我们需要前向声明ViewController类呢?一种常见的情况是,当我们的AppDelegate类中有一个属性或方法需要引用ViewController类时。在这种情况下,我们可以使用@class来告诉编译器,ViewController类存在于我们的项目中,以便编译器不会报错。然后,在AppDelegate.m文件中,我们可以使用#import来实际导入ViewController的头文件。

解决方法是,在AppDelegate.h中使用@class来前向声明ViewController类,并在AppDelegate.m中使用#import导入ViewController的头文件。这样可以避免在编译时出现循环引用或其他问题。

总结起来,我们在AppDelegate.h中使用@class而不是#import来引用ViewController类的原因是为了避免在编译时出现循环引用或其他问题。解决方法是在AppDelegate.h中使用@class进行前向声明,并在AppDelegate.m中使用#import导入ViewController的头文件。

0
0 Comments

在AppDelegate.h中使用@class而不是#import导入ViewController的原因是,避免了引入ViewController.h文件所带来的额外开销。

具体解决方法是,在AppDelegate.h文件中使用@class来前向声明ViewController类,而不是直接使用#import导入ViewController.h文件。

前向声明可以简单地理解为告诉编译器,有一个名为ViewController的类存在,但不需要具体的属性、方法等信息。这样一来,在编译过程中,编译器只需要知道ViewController类的存在,而无需加载ViewController.h文件,从而节省了一定的编译时间和资源。

在使用@class进行前向声明后,如果在AppDelegate.m文件中需要使用ViewController类的具体属性、方法等信息,仍然需要使用#import导入ViewController.h文件。因为在.m文件中,编译器需要知道ViewController类的具体实现。

总结一下,通过使用@class进行前向声明,可以减少编译时间和资源消耗,提高代码编译的效率。

以下是问题的原因和解决方法总结:

问题原因:在AppDelegate.h中使用#import导入ViewController.h文件会带来额外的开销。

解决方法:使用@class进行前向声明来替代直接#import导入ViewController.h文件,以减少编译时间和资源消耗。

希望以上内容对您有所帮助。

0
0 Comments

在AppDelegate.h中,为什么要使用@class而不是#import导入ViewController?

问题的原因是,使用@class是一种前向声明,这样编译器就知道ViewController这个名称应该代表什么意思。使用尽可能少的#import语句可以加快编译速度。假设有一个文件a.h,其中包含#import "b.h"。现在,导入a.h的每个文件自动导入b.h,这增加了编译器的工作量。通过使用前向声明,我们通常可以避免这种额外的导入,从而避免给编译器增加额外的工作。

项目越大,类的层次结构和依赖关系越复杂,这些#import语句就可能成为一个问题。所以在可能的情况下使用前向声明是一个好习惯。

编辑后,根据评论,另一个重要的用例浮出水面:解决循环依赖。例如,如果类A想引用类B,而类B也想引用类A,那么其中一个类必须在另一个之前定义。但是因为它们需要知道对方,所以我们有了一个悖论。解决方法如下:

// 告诉编译器:B将是一个类类型。

B;

// 现在我们可以定义A了,编译器有足够的信息来知道B代表什么意思。

A : NSObject {

B *b;

}

// 由于A现在已经定义,我们可以定义B了。

// 循环依赖已解决。

B : NSObject {

A *a;

}

除了编译时间之外,实际程序性能会受到这两种方法的影响吗?

正如dreamlax所说,运行时不受影响。这只会影响编译过程,以便编译器对名称(类型)有一个大致的概念。在一个.m文件中,如果要使用该类的实例,需要进行#import,这样编译器就可以知道所有细节,比如方法名和其他符号。

作为一个测试,我将替换为#import,看看会发生什么,并从.m中删除#import,非常奇怪,我得到一个编译器错误Expected specifier-qualifier-list before RootViewController - 为什么会这样?

没有具体的代码,我不能确定,但这个错误意味着编译器不知道RootViewController是什么。所以你缺少一个前向声明或导入该类型。

查看这个链接:dl.dropbox.com/u/14211240/compile%20error.png我重新启动了Xcode,但没有改变。

是的,但是RootViewController.h是什么样子的?

啊,可能是因为RootViewController.h反过来导入了AppDelegate.h吗?- 这就是问题所在,谢谢。

看到我的编辑回答:你找到了前向声明最初为什么必要的实际用例。

谢谢,所有这些都非常有用的帮助。我最后一个相关问题是.h文件和.m文件之间的关系 - 通过导入.h文件,你不是也在实质上导入了它的.m文件吗?也就是说,编译器将它们视为一对?在这种情况下,在.m中使用#import应该对导入.h的所有其他类的编译时间来说是相似的,因为每个类都在寻找.h的.m实现,对吗?

Xcode只会一次向编译器传递一个.m文件。然后,.m文件导入它所需要的所有.h文件。这就是为什么你可以设置.m文件的目标成员,但不能设置.h文件的原因。编译器不会将.m文件和.h文件视为一对,它不知道(也不关心)两者之间的任何关系。实际上,您可以根据需要为.h文件命名,.h扩展名只是一种约定。

0