Есть ли способ вызвать [anObject performSelector]; с более чем двумя объектами? Я знаю, что вы можете использовать массив для передачи нескольких аргументов, но мне было интересно, существует ли способ более низкого уровня для вызова функции, которую я уже определил с помощью более двух аргументов без использования вспомогательной функции с nsarray аргументов.
PerformSelector с более чем двумя объектами
Ответ 1
Либо (1) Используйте NSInvocation или (2) прямо использовать objc_msgSend
.
objc_msgSend(target, @selector(action:::), arg1, arg2, arg3);
(Примечание: убедитесь, что все аргументы id
, иначе аргументы могут быть отправлены неправильно.)
Ответ 2
Вы можете расширить класс NSObject
следующим образом:
- (id) performSelector: (SEL) selector withObject: (id) p1
withObject: (id) p2 withObject: (id) p3
{
NSMethodSignature *sig = [self methodSignatureForSelector:selector];
if (!sig)
return nil;
NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig];
[invo setTarget:self];
[invo setSelector:selector];
[invo setArgument:&p1 atIndex:2];
[invo setArgument:&p2 atIndex:3];
[invo setArgument:&p3 atIndex:4];
[invo invoke];
if (sig.methodReturnLength) {
id anObject;
[invo getReturnValue:&anObject];
return anObject;
}
return nil;
}
(см. NSObjectAdditions из проекта Three20.) Тогда вы даже можете расширить описанный выше метод, чтобы использовать varargs и массив аргументов с нулевым завершением, но это лишнее.
Ответ 3
Дополнительной опцией, когда требуется отправить несколько объектов с помощью performSelector
, является (если это достаточно легко сделать), чтобы изменить метод, который вы хотите вызвать, чтобы принять объект NSDictionary
вместо нескольких параметров, вы сможете отправлять столько, сколько хотите в словаре.
Например
У меня был метод, подобный этому, который имел 3 аргумента, и мне нужно было вызвать его из performSelector -
-(void)getAllDetailsForObjectId:(NSString*)objId segment:(Segment*)segment inContext:(NSManagedObjectContext*)context{
Я изменил этот метод, чтобы использовать словарь для хранения аргументов
-(void)getAllDetailsForObject:(NSDictionary*)details{
поэтому мне удалось легко вызвать метод
[self performSelector:@selector(getAllDetailsForObject:) withObject:@{Your info stored within a dictionary}];
Думал, что я тоже буду делиться этим как альтернативный вариант, поскольку он работает для меня.
Приветствия