它沒有導入標題隱藏。子類「知道」超類「知道」的一切。這是單一繼承設計的優勢之一。考慮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