2012-09-20 69 views
1

這是我在我的班級我的一個實現文件...這個分類爲什麼起作用?範疇與類擴展

代碼設置#1

@interface MyViewController (PrivateMethods) 
- (NSString *)myPrivateMethod; 
@end 

@implementation MyViewController 
- (void)viewDidLoad 
{ 
    NSString *myString = [self myPrivateMethod]; 
    NSLog(@"%@", myString); 
} 

- (NSString *)myPrivateMethod 
{ 
    return @"someString"; 
} 
@end 

有了這個代碼,一切正常,並記錄「someString 」。

但不應該我的代碼看起來不同?我實際上是偶然使用這一類(我有複製/粘貼的東西,沒有注意到「PrivateMethods」在那裏;我打算使用類擴展)。

應該不是我的代碼實際上看起來像下列之一:

代碼設置#2

@interface MyViewController() 
- (NSString *)myPrivateMethod; 
@end 

@implementation MyViewController 
.... 

或者:

代碼設置#3

@interface MyViewController (PrivateMethods) 
- (NSString *)myPrivateMethod; 
@end 

@implementation MyViewController (PrivateMethods) 
.... 

什麼這種情況背後的細微差別是什麼?代碼設置#1與代碼設置#2有什麼不同?

編輯:有關安裝程序#3

是什麼設置它像這樣完成的問題?這是否會「工作」?

@interface MyViewController (PrivateMethods) 
- (NSString *)myPrivateMethod; 
@end 

@implementation MyViewController 
- (void)viewDidLoad 
{ 
    NSString *myString = [self myPrivateMethod]; 
    NSLog(@"%@", myString); 
} 
@end 

@implementation MyViewController (PrivateMethods) 
- (NSString *)myPrivateMethod 
{ 
    return @"someString"; 
} 
@end 

回答

2

選擇器只是在運行時被壓入相同的平面命名空間。編譯器不添加額外的代碼來區分選擇器是在類別中定義的方法(當消息傳遞時) - 它完全平坦。

類別的符號導出方式不同,但這對加載運行時並不重要。

您應該通常使用安裝程序#3:如果方法在類別中聲明,應該在類別的@implementation中定義。編譯器會偶爾保存,這是一個更純的結構。 (當然,並非每種方法都屬於一個類別)。類似地,在@interface的聲明,應在相應@implementation來定義,並在類延續(@interface MONClass())聲明的定義也應出現在初級@implementation

@implementation MONClass 
// add your @interface MONClass definitions here 
// also add your @interface MONClass() definitions here 
@end 

更新問題

是,那會很好。所有你需要做的是#import的頭部包含@interface MyViewController (PrivateMethods)。我實際上是在一些課上做這個,按主題進行分類/組織。

通常,「私有方法」在類繼續中聲明,但沒有必要這樣做(ivars/properties OTOH ...)。

+0

用另一個關於安裝程序#3的問題更新我的問題。非常感謝! – MikeS

+2

我認爲在這種情況下(最近的)Clang會將另一個未聲明的方法的定義視爲同一個「@實現」的聲明也是很重要的。 –

+0

我「有點」意識到喬希。這是否僅僅是新的Xcode? – MikeS

相關問題