executeSelector с более чем 2 объектами - PullRequest
16 голосов
/ 27 февраля 2010

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

Ответы [ 3 ]

49 голосов
/ 27 февраля 2010

Либо (1) использовать NSInvocation или (2) напрямую использовать objc_msgSend.

objc_msgSend(target, @selector(action:::), arg1, arg2, arg3);

(Примечание: убедитесь, что все аргументы id, иначе аргументы могут быть отправлены неправильно.)

14 голосов
/ 27 февраля 2010

Вы можете расширить класс 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 и массив аргументов с нулевым символом в конце, но это излишне.

0 голосов
/ 10 февраля 2015

Дополнительной опцией, когда вам требуется отправить несколько объектов с performSelector, является (если это достаточно просто сделать) изменение метода, который вы хотите вызвать, для получения объекта NSDictionary вместо нескольких параметров, как вы ' Вы сможете отправлять столько слов, сколько хотите в словаре.

Например

У меня был метод, похожий на этот, который имел 3 аргумента, и мне нужно было вызвать его из executeSelector -

-(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}];

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

Приветствия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...