Полиморфные блоки свойств в Obj C как функции обратного вызова - PullRequest
3 голосов
/ 05 декабря 2011

Я хочу использовать блок в качестве функции обратного вызова. Я храню свой блок как свойство в своем классе, которое выполняет обратный вызов:

@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 как свойство / свойство. Затем я хочу установить его так:

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 Ответ

2 голосов
/ 05 декабря 2011

Передайте ваш параметр как NSNumber. Вы можете восстановить его исходный тип, используя -objCType, который вернет строку, указывающую кодировку типа . Таким образом, вам не нужно полиморфировать вызов функции.

Либо, если NSNumber окажется слишком негибким, просто создайте свой собственный класс данных Argument, который кодирует любую необходимую вам информацию. При необходимости вы также можете создать класс данных Result для типа возвращаемого значения.

...