Нужно / хотите передать NSError ** в качестве аргумента для executeSelector - PullRequest
3 голосов
/ 21 мая 2009

Я хочу вызвать селектор метода, который имеет обычный аргумент NSError **:

-(int) getItemsSince:(NSDate *)when dataSelector:(SEL)getDataSelector error:(NSError**)outError  {
    NSArray *data = nil;
    if([service respondsToSelector:getDataSelector]) {
        data = [service performSelector:getDataSelector withObject:when withObject:outError];
        // etc.

... что не нравится компилятору:

warning: passing argument 3 of 'performSelector:withObject:withObject:' from incompatible pointer type

Есть ли способ обойти указатель в объекте?

Ответы [ 3 ]

14 голосов
/ 21 мая 2009

Check NSInvocation , что позволяет вам "выполнять выбор" гораздо более гибким способом.

Вот код, с которого можно начать:

if ([service respondsToSelector:getDataSelector]) {
    NSArray *data;
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
        [service methodSignatureForSelector:getDataSelector]];
    [invocation setTarget:delegate];
    [invocation setSelector:getDataSelector];
    // Note: Indexes 0 and 1 correspond to the implicit arguments self and _cmd, 
    // which are set using setTarget and setSelector.
    [invocation setArgument:when atIndex:2]; 
    [invocation setArgument:outError atIndex:3];
    [invocation invoke];
    [invocation getReturnValue:&data];
}
3 голосов
/ 21 мая 2009

NSError ** не является объектом (id), который требуется executeSelector для каждого из аргументов withObject. Вы можете перейти к NSInvocation, но это кажется большой работой, если вы хотите использовать только одно сообщение. Попробуйте определить метод промежуточного селектора, который принимает в качестве аргумента вашу обернутую NSError ** в объекте, и пусть этот метод выполняет на нем executeSelector (что, я думаю, было, вероятно, тем, что вы имели в виду в конце вашего вопроса?)

2 голосов
/ 21 мая 2009

Я не уверен, но вы можете взглянуть на использование NSInvocation вместо -performSelector:withObject:withObject. Поскольку NSInvocation принимает аргументы типа void*, он может / должен позволять вам устанавливать в качестве аргумента все, что вы хотите.

Для этого потребуется несколько строк кода, чем для простого вызова performSelector:, но, вероятно, это будет удобнее, чем заключать указатель в объект.

...