它没有导入标题隐藏。子类“知道”超类“知道”的一切。这是单一继承设计的优势之一。考虑3个班级;
ClassA.h
#import <Foundation/Foundation.h>
@class ClassB;
@interface ClassA : NSObject {
ClassB *bClass;
}
@property(nonatomic, retain) ClassB *bClass;
@end
ClassA.m
#import "ClassA.h"
#import "ClassB.h"
@implementation ClassA
@synthesize bClass;
-(ClassB *) bClass{
return [[ClassB alloc] init];
}
@end
ClassB的:
#import <Foundation/Foundation.h>
@class ClassA;
@interface ClassB : NSObject {
ClassA *aClass;
NSString *name;
}
@property(nonatomic, retain) ClassA *aClass;
@property(nonatomic, retain) NSString *name;
@end
ClassB.m
#import "ClassB.h"
#import "ClassA.h"
@implementation ClassB
@synthesize aClass;
@synthesize name;
-(NSString *) name { return @"steve";}
@end
现在创建ClassA的子类: ClassC.h
#import <Foundation/Foundation.h>
#import "ClassA.h"
@interface ClassC : ClassA {
}
@end
ClassC.m
#import "ClassC.h"
@implementation ClassC
@end
当你调用ClassC的bclass的名称方法:
#import "ClassC.h"
...
ClassC *c=[[ClassC alloc] init];
NSLog(@"c %@",[[c bClass] name]); //prints "c steve"
子类固有进口头他们的超类实现文件。
Edit01:
从评论:
试试这个:在ClassA.h定义一个宏, 然后尝试使用ClassC.m (宏观不导入ClassA.h有)。它 将不会编译
在所有应有的尊重,我认为这是不正确的。以下是编译实际代码并运行:
ClassA.h
#import <Foundation/Foundation.h>
#define aMacro 5
@class ClassB;
@interface ClassA : NSObject {
ClassB *bClass;
}
@property(nonatomic, retain) ClassB *bClass;
@end
ClassC.h
#import <Foundation/Foundation.h>
#import "ClassA.h"
@interface ClassC : ClassA {
}
-(void) logMacro;
@end
ClassC.m
#import "ClassC.h"
@implementation ClassC
-(void) logMacro{
NSLog(@"aMacro=%d",aMacro);
}//-------------------------------------(void) logMacro------------------------------------
@end
运行时间:
#import "ClassC.h" //the only header imported of the three classes ./////////
...
ClassC *c=[[ClassC alloc] init];
NSLog(@"c %@",[[c bClass] name]);
[c logMacro]; //prints 5
显然,ClassC.m仅仅基于在ClassC.h中导入ClassA.h(它必须做的子类)来了解ClassA.h中定义的宏。
ClassC将不知道在ClassA.m中定义的宏,但这是因为在实现中定义的宏实际上并不是该类的逻辑部分。 ClassA并不知道这个宏。这样的宏不在类的名称空间中,它只是由编译器执行的简单文本替换。 ClassC不知道这样的替换,它知道ClassA在其方法的某个地方使用了实际的'5'。 ClassC不能固有这样一个宏,因为没有什么是固有的。
ClassC知道ClassA中定义的宏,因为编译器生成的ClassC的真正逻辑头是由导入创建的链中所有头的并集。 ClassC 知道所有ClassA都知道它知道Foundation框架知道的所有内容。
ClassC以类ClassA的方式了解ClassB。 @class指令使编译器期待ClassB的定义,并在ClassA.m中找到它。幕后没有大量头文件的秘密输入。这是父母面临的问题。
想过更多之后,我意识到这是真的。编译器并没有做任何事情,事情正在被导入,它只是隐藏在其他头文件和前缀中。谢谢! – jbrennan 2009-11-13 19:26:27
没有大量导入预编译头文件。 @class指令使编译器向前搜索以查找实现文件中定义的头。你可以通过创建具有循环引用的类来看到这一点。在我的答案中看到我的例子。 – TechZen 2009-11-14 17:15:07
“没有大量导入预编译头文件。” 在Xcode文档中查找“项目头文件”。问题是关于UIKit类;你的例子不适用。 – NSResponder 2009-11-15 19:49:43