2009-02-22 37 views
14

我想在Objective-C中構建方法的NSArray。如何在Objective-C中構建類方法的NSArray(或NSMutableArray)?

(我想在這裏完成的東西像在C以下)

我有口這Objective-C和我不知道如何 建立的數組函數指針(在Objective-c世界中, 類方法)在編譯時。

在Objective-C中,我有以下幾點。

- (void)handleCommandA { ... } 
- (void)handleCommandB { ... } 

/* Now how to add above 2 functions into NSArray? */ 
NSArray *handler_table = [NSArray arrayWithObjects:... ]; /* This doesn't seem to work. */ 

回答

5

使用NSValue。

例如:

NSArray* handlers = [NSArray arrayWithObjects:[NSValue valueWithPointer:handleA] ... ]; 

然後訪問:

handleptr* handle = (handlerptr*)[[handlers objectAtIndex:0] pointerValue]; 
handle(foo_bar); 
28

這裏的問題是要綁定這些函數,您必須使用返回SEL類型的selector關鍵字。這是一個指針類型,而NSArray存儲對象。

因此,您有三個選項;

  1. 使用常規的C型陣列
  2. 摺疊功能爲一個NSObject派生類,將調用它們。
  3. 使用協議。

第二個可能更好,爲此,您可以使用NSValue類來保存選擇器結果。例如;

NSValue* selCommandA = [NSValue valueWithPointer:@selector(handleCommandA:)]; 
NSValue* selCommandB = [NSValue valueWithPointer:@selector(handleCommandB:)]; 

NSArray *handler_table = [NSArray arrayWithObjects:selCommandA, selCommandB, nil ]; 

當您從數組中檢索到正確的條目時,要將其轉換回來;

SEL mySelector = [selCommand pointerValue]; 
[someObject performSelector:mySelector]; 

(注意:我假設,從這些意在作爲對象的方法,而不是全局函數的Objective-C的語法。如果你想在全球範圍內使用它們,那麼你應該把它們寫爲你會用普通的C.)

另一種選擇是將命令方法正式化爲協議。這使您可以編寫適用於實現該協議的任何對象的功能,編譯器將提供比僅調用選擇器更多的檢查功能。

E.g.

// some header 
@protocol CommandHandler 
@required 
-(void) handleCommandA; 
-(void) handleCommandB; 
@end 

// some other header 
@interface someClass : NSObject<CommandHandler> 
{ 
// you will receive compiler warnings if you do not implement the protocol functions 
} 

然後,您的處理和調度代碼被寫入與「CommandHandler」類型的對象一起工作。例如

-(void) registerForCommands:(CommandHandler*)handler 
+0

我寧願使用字符串代替指針,因爲這將使得調試更加容易。看看NSStringFromSelector()和NSSelectorFromString()。 – jmah 2009-05-17 09:10:39

4

在Objective-C中,您不會傳遞方法;你通過選擇器,這基本上是方法的規範名稱。然後,要使對象響應選擇器消息,請發送它performSelector:。例如:

NSString *exampleString = [NSString stringWithString:@"Hello"]; 
SEL methodName = @selector(stringByAppendingString:); 
    // ^This is the selector. Note that it just represents the name of a 
    // message, and doesn't specify any class or implementation 
NSString *combinedString = [exampleString performSelector:methodName withObject:@" world!"]; 

你會想什麼是讓你包含感興趣的選擇的名稱NSString的陣列可以使用功能NSStringFromSelector()做到這一點。然後,當您要使用它們時,請在字符串上調用NSSelectorFromString()以獲取原始選擇器並將其傳遞給適當對象的performSelector:。(如上例所示,接收器不在選擇器中編碼 - 只是方法名稱 - 因此您可能還需要存儲接收器。)

相關問題