С блоками вам, вероятно, придется совершить магию va_args
. Вызов селектора с переменными аргументами может быть выполнен, но вы, вероятно, захотите, чтобы некоторые помощники сделали его менее болезненным.
NSObject + performSelectorWithArgsArray.h
@interface NSObject (performSelectorWithArgsArray)
- (id)performSelector:(SEL)sel withArgsArray:(NSArray *)args;
@end
NSObject + performSelectorWithArgsArray.m
@implementation NSObject (performSelectorWithArgsArray)
- (id)performSelector:(SEL)sel withArgsArray:(NSArray *)args {
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:
[self methodSignatureForSelector:sel]];
[inv setSelector:sel];
[inv setTarget:self];
for (int i = 0; i < args.count; i++) {
id a = [args objectAtIndex:i];
[inv setArgument:&a atIndex:2 + i]; // 0 is target, 1 is cmd-selector
}
[inv invoke];
NSNumber *r;
[inv getReturnValue:&r];
return r;
}
@end
А затем используйте это так:
#import "NSObject+performSelectorWithArgs.h"
@interface SomeClass : NSObject
@end
@implementation SomeClass
- (NSNumber *)withA:(NSNumber *)a withB:(NSNumber *)b {
return [NSNumber numberWithInt:a.intValue + b.intValue];
}
@end
- (void)someMethod {
SomeClass *a = [[SomeClass alloc] init];
SEL sel = @selector(withA:withB:);
NSArray *args = [NSArray arrayWithObjects:
[NSNumber numberWithInt:2],
[NSNumber numberWithInt:3],
nil];
NSNumber *r = [a performSelector:sel withArgsArray:args];
NSLog(@"%d", r.intValue);
}
Если вы решите сделать что-то подобное, я рекомендую вам действительно прочитать о том, как работает NSInvocation
, поскольку он может сильно кусаться. Не уверен, что это можно сделать, не требуя, чтобы все аргументы и возвращаемое значение были объектами.