Подтвердить что ты не робот

PerformSelector с более чем двумя объектами

Есть ли способ вызвать [anObject performSelector]; с более чем двумя объектами? Я знаю, что вы можете использовать массив для передачи нескольких аргументов, но мне было интересно, существует ли способ более низкого уровня для вызова функции, которую я уже определил с помощью более двух аргументов без использования вспомогательной функции с nsarray аргументов.

4b9b3361

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

Думал, что я тоже буду делиться этим как альтернативный вариант, поскольку он работает для меня.

Приветствия