问题
根据我的理解,在ClassA需要包含ClassB的头文件同时ClassB需要包含ClassA的头文件的情况下,为了避免任何循环引用,应该使用forward-class声明。#import
本质就是一个简单的#ifndef
,因此引用头文件只会出现一次。
问题是:我们何时该使用#import
何时使用@class
,有时在使用@class的情况下,会出现编译器警告,信息如下:
warning: receiver ‘FooController’ is a forward class and corresponding @interface may not exist.
分析
如果你看到如下警告信息:
warning: receiver ‘MyCoolClass’ is a forward class and corresponding @interface may not exist
说明你需要使用#import
导入文件,但是你可以在实现文件(.m)中使用#import
,头文件中使用@class
这样的方式实现。
@class
通常不是为了替代#import
,它只是将需求转移到信息更有价值的地方。
比如:
示例
如果使用@class MyCoolClass
,编译器就会知道如下信息:
MyCoolClass *myObject;
除了关注MyCoolClass
是一个可用的类,无需担心其他任何东西,它应该为指向它的指针预留空间(实际上,只是一个指针)。
因此,在头文件中,@class
满足了90%的需求。
然而,如果你需要创建或者访问myObject
的一个方法或者属性,你将需要让编译器知道那些方法是什么。此时,你需要在(实现文件).m
文件中使用#import "MyCoolClass.h"
,告诉编译器除了这是个类之外的其他额外信息。
总结
前置声明仅仅告诉编译器:“嗨,我知道我声明的这个家伙你不认识,但是当我使用@MyClass
声明它后,我承诺我稍后将会在实现文件(.m)
中#import
它。”