2011-09-08 78 views
0

在objective-c中,可以將一個@dynamic添加到屬性中。Objective-C有類似C++虛函數的東西嗎?

這對普通的實例方法也是可行的嗎?

編輯 我覺得我還不夠清楚。

我要做到以下幾點:

@interface MyClass 
@property (retain) NSObject *somePropertyObject; 
- (void) myMethod; 
@end 

@implementation MyClass 

@dynamic somePropertyObject; 

//Make myMethod dynamic. I do not want to implement it. Like C++ Virtual 

@end 

回答

2

我想你可能會問如何聲明將實施一段時間後,其他地方的方法。

Objective-C的做法是使用Protocols

您聲明一個協議這樣的,通常在頭文件

@protocol MyProtocol <NSObject> { 
@optional 
    - (void)optionalMethod; 
@required 
    - (void)requiredMethod; 
} 
@end 

這聲明兩種方法,一種是可選的,並且需要一個。要使用此協議之前,宣佈將實施

@interface MyConformingClass : NSObject <MyProtocol> { 
} 
// you don't have to redeclare methods that are declared in the protocol 
@end 

這個新類是在編譯時檢查的requiredMethod所以它必須實現它的執行協議中的類時聲明的一致性,但它可以選擇是否不實施

@interface RequiringClass : NSObject { 
    MyConformingClass <MyProtocol> *conformingClassObject; 
} 
… 
@end 

再次optionalMethod

現在,需要對象的實例,以符合協議的任何類可以聲明此,例如,在接口,這是在編譯期進行檢查

要確保貼合類實現@optional方法,我們可以用這個結構輕巧的這個

if [conformingClassObject respondsToSelector:@selector(optionalMethod)] { 
    [conformingClassObject optionalMethod]; 
} else { 
    // Do something here because the optional method isn't provided 
} 

例子遍佈可可 - 這是一類可以提供一個列表它希望將其用於委託的操作,委託人採用協議並提供這些委託方法的實現。然後調用對象可以檢查這個委託是否在運行時響應這些方法,如上所述,並調用這些方法來執行操作,或者在需要時提供信息。

這在Objective-C中用得相當多,其中類提供了一些他們希望其他類可以執行的方法列表,這與虛擬函數不同,虛函數是類聲明函數,它希望子類提供實現。特別是因爲組合在語言上優於繼承。而不是創建一個提供實現的子類,而是創建另一個可以做同樣事情的類,並在該類中添加對該類的引用。

+1

協議類似於Java/C#接口,在C++中,它們最接近於沒有數據成員的抽象類以及所有純虛擬方法。我認爲一個協議僅僅是爲了在運行時提供實現的單個類聲明一個方法而有點矯枉過正。就個人而言,我會爲多個類將實現(或不是)相同方法的情況保存協議。 – ipmcc

+1

想想iOS,其中委託用於將數據從堆棧頂部的視圖傳遞到視圖控制器。一個常見的做法是委派,這只是一個階層與另一個階層之間的渠道。 – Abizern

2

@dynamic僅僅是寫着編譯器指令:「不要打擾產生存取該物業的,我我會提供我自己的。「

對其他方法使用@dynamic不會有幫助,因爲編譯器不會爲您生成除訪問器以外的任何方法,當然您仍然提供其他方法。

你想完成什麼?

+0

我想要一個沒有實現它的方法的聲明。它的實現是在運行時提供的。像一個虛擬的C++函數。 –

+0

@Mats每個Objective-C方法都是C++的虛擬方法。你是否指C++中的純虛擬成員函數? – Yuji

5

如果您的意思是「如何聲明一個方法,但不提供我將在運行時提供的定義?」然後很簡單,只需使用一個類別。就像這樣:「無法識別的選擇」

@interface MyObject : NSObject 

// Methods I'll define 
- (void)doFoo; 

@end 

@interface MyObject (DynamicallyProvidedMethods) 

// Methods I won't 
- (void)myDynamicMethod; 

@end 


@implementation MyObject 

// Methods I'll define 
- (void)doFoo 
{ 
} 

@end 

編譯器不會抱怨,但如果調用-myDynamicMethod在運行時,除非你已經在某種程度上提供了一個實現它,它會與崩潰當然,您可以通過調用respondsToSelector來在運行時測試它:相關地,如果你打算做一個基本類的純虛擬方法的近似等價物,那麼我建議提供一個空的實現,如果它沒有被子類重寫,則在被調用時會斷言。你能做到這一點,像這樣:

NSAssert((class_getInstanceMethod([self class], _cmd) == class_getInstanceMethod([MyObject class], _cmd)), 
    @"Subclass of %@ must override -%@", 
    NSStringFromClass([MyObject class]), 
    NSStringFromSelector(_cmd)); 

// ...where overridesSelector:ofBaseClass: looks like: 
// 
//  return ; 

當然,這不會提醒您在編譯時的問題,但總比沒有好。

HTH

相關問題