2011-12-05 37 views
3

我想使用塊作爲回調函數。我在我的塊存儲在我的類,它調用回一個屬性:Obj C中的多態屬性塊作爲回調函數

@interface MyParameter 
{ 
    float myValue; 
    void (^callback)(float); 
} 
@property(copy) void (^callback)(float); 
@end 

@implementation MyParameter 
@synthesize callback; 

- (void) valueChanged 
{ 
    callback(myValue); 
} 
@end 

然後我設置回調:

MyParameter * param = [[MyParameter alloc] init]; 
[param setCallback:^(float value) { [self doSomethingWithValue:value]; }]; 

到目前爲止那麼簡單。實際上,MyParameter是一個通用抽象,它保存運行時確定數量的不同類型參數的詳細信息。我可以有連續的(float)值,離散值(int)和布爾值。所以接下來,我試過這個:

@interface MyParameter 
{ 
    float floatVal; 
    int intVal; 
    void (^contCallback)(float); 
    void (^discCallback)(int); // And a boolean one too but let's keep this short 
    ParamType type; // enum of types ie enum ParamType { Continuous, Discrete, Boolean }; 
} 
@property(copy) void (^contCallback)(float); 
@property(copy) void (^discCallback)int); 
@end 

@implementation MyParameter 
@synthesize contCallback; 
@synthesize discCallback; 

- (void) valueChanged 
{ 
    switch (type) { 
    case Continuous: 
     contCallback(floatVal); 
     break; 
    case Discrete: 
     discCallback(intVal); 
     break; 
    // Leave default out for brevity 
    } 
} 
@end 

哪個越來越醜。我想保留一個^callback作爲ivar /財產。然後我想設置這樣的:

MyParameter *contParam = [[MyParameter alloc] init]; 
[contParam setCallback:(^float value) { [self doSomethingContinuous:value]; }]; 

MyParameter *discreteParam = [[MyParameter alloc] init]; 
[discreteParam setCallback:(^int value) { [self doSomethingDiscrete:value]; }]; 

裏面MyParametervalueChanged方法將保留從上面的switch/case,決定如何在傳遞給回調。

這可能嗎?

回答

2

將您的參數作爲NSNumber傳遞。您可以使用-objCType恢復其原始類型,它將返回一個字符串,指示type encoding。這樣你就不必變形你的函數調用。或者,如果NSNumber結果太不靈活,只需創建自己的Argument數據類,它可以編碼您需要的任何信息。如有必要,還可以爲返回類型創建一個Result數據類。

+0

使用'NSNumber'工作得非常好,回想起來這似乎很明顯,這是一個正確的好兆頭。感謝Rob。 –