Obj C中的多态属性块作为回调函数

时间:2011-12-05 15:56:17

标签: objective-c objective-c-blocks

我想使用块作为回调函数。我将我的块存储为我的类中的一个属性,用于执行回调:

@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 / property。然后我想这样设置:

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

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

MyParameter内部,我的valueChanged方法会保留上面的switch/case,以决定传入回调的内容。

这可能吗?

1 个答案:

答案 0 :(得分:2)

将参数传递为NSNumber。您可以使用-objCType恢复其原始类型,这将返回表示type encoding的字符串。这样您就不必对函数调用进行多态化。

或者,如果NSNumber过于缺乏灵活性,只需创建自己的Argument数据类,即可对您需要的任何信息进行编码。如有必要,您还可以为返回类型创建Result数据类。