Objective c 目标C:前向类声明

Objective c 目标C:前向类声明,objective-c,c-preprocessor,forward-declaration,Objective C,C Preprocessor,Forward Declaration,我正在编写一个多视图应用程序,它利用一个名为RootViewController的类在视图之间切换 在我的MyAppDelegate标题中,我创建了一个名为RootViewController的RootViewController的实例。我见过这样的例子,@class指令被用作“前向类声明”,但我不太确定这意味着什么或实现了什么 #import <UIKit/UIKit.h> @class RootViewController; @interface MyAppDelegate .

我正在编写一个多视图应用程序,它利用一个名为
RootViewController
的类在视图之间切换

在我的
MyAppDelegate
标题中,我创建了一个名为
RootViewController
RootViewController
的实例。我见过这样的例子,@class指令被用作“前向类声明”,但我不太确定这意味着什么或实现了什么

#import <UIKit/UIKit.h>
@class RootViewController;
@interface MyAppDelegate
.
.
.
#导入
@类RootViewController;
@接口MyAppDelegate
.
.
.

它基本上告诉编译器类
RootViewController
存在,但没有指定它的确切外观(即:它的方法、属性等)。您可以使用它来编写包含
RootViewController
成员变量的代码,而不必包含完整的类声明

这在解决循环依赖关系时特别有用-例如,假设
ClassA
有一个
ClassB*
类型的成员,而
ClassB
有一个
ClassA*
类型的成员。在
ClassA
中使用它之前,需要声明
ClassB
,但在
ClassB
中使用它之前,还需要声明
ClassA
。转发声明允许您通过告诉
ClassA
存在
ClassB
来克服这一问题,而无需实际指定
ClassB的完整规范

您倾向于发现大量前向声明的另一个原因是,有些人采用前向声明类的约定,除非它们绝对必须包含完整声明。我不完全记得了,但这可能是苹果公司在其Objective-C指导风格指南中推荐的东西

继续我上面的例子,如果
ClassA
ClassB
的声明分别在
ClassA.h
ClassB.h
文件中,那么您需要导入
#导入
在另一个类中使用它的声明。使用转发声明意味着您不需要
#import
,这会使代码更漂亮(特别是当您开始收集相当多的类时,每个类在使用时都需要一个`#import),通过最小化编译器在编译任何给定文件时需要考虑的代码量来增加编译性能。

作为一个旁白,尽管问题只涉及Objtovi-C中的前向声明,但是所有的过程注释同样适用于C和C++(以及可能许多其他语言)的编码,它还支持转发声明,通常用于相同的目的。

转发声明主要是为了避免循环导入,即一个文件导入另一个文件,该文件导入第一个文件等。基本上,在导入文件时,在构建项目时,文件的内容在导入点被替换,然后将其馈送到编译器。如果您有循环导入,您将有一个永远不会编译的无限循环。幸运的是,xcode将在尝试之前告诉您这一点。转发声明说“不要导入这个类,只知道它存在。”如果没有导入或转发声明,您会得到一个错误,即不存在这样的类。

@class
转发类声明
(不完整类型)-只需告诉编译器这个类存在。在这种情况下,编译器对类型内存布局(类大小、成员或方法)一无所知。这就是为什么只能通过引用和指针来定义类

优点:

  • 缩短构建时间
  • 中断循环引用

所以,我想我不明白为什么在MyAppDelegate.h中创建RootViewController对象是不够的。看起来有些多余,但我肯定我遗漏了一些基本的东西。。。编辑:啊,;刚刚看了你的编辑,太好了。简明的谢谢。转发声明类的一个原因是如果A有一个指向B的指针,而B的指针又是指向A的指针。不能从B.h导入A.h,也不能从A.h导入B.h,因为它是循环依赖项。头文件中的转发声明会处理这个问题。A.m imports B.h.B.m imports A.h.@Rogerwernerson:这不是我的答案所说的吗?那么,我们能在其他情况下使用@class而不是import吗?或者什么样的情况绝对需要导入,而@class无法完成?我猜您不会“创建实例”,而是“声明指向的指针”。这是正确的吗?