2010-02-27 9 views
16

¿Hay alguna manera de llamar a [anObject performSelector]; con más de 2 objetos? Sé que puede usar una matriz para pasar argumentos múltiples, pero me preguntaba si había una forma de nivel inferior para llamar a una función que ya he definido con más de 2 argumentos sin usar una función auxiliar con un nsarray de argumentos.performSelector con más de 2 objetos

Respuesta

48

Cualquiera (1) Utilice un NSInvocation o (2) use directamente objc_msgSend.

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

(Nota: asegúrese de todos los argumentos son id 's, de lo contrario los argumentos no podrían ser enviados correctamente.)

+12

Al utilizar objc_msgSend, tendrá que import según: http://stackoverflow.com/questions/4896510/how-to-import-nsobjcruntime-h -to-use-objc-msgsend –

+1

esa última nota que hiciste para asegurarte de que todos los argumentos sean del tipo id ... ¿puedes seguir explicando? o proporcionar algún recurso, por favor? no puedo encontrar ninguno. –

14

Usted puede extender la clase NSObject así:

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

(Consulte NSObjectAdditions del proyecto Three20.) Entonces, incluso podría extender el método anterior para usar varargs y una matriz de argumentos sin terminación, pero eso es exagerado.

0

Una opción adicional, cuando necesita enviar múltiples objetos con performSelector es (si es fácil hacerlo) modificar el método que desea llamar para tomar un objeto NSDictionary en lugar de varios parámetros, ya que podrá para enviar tantas como quieras dentro del diccionario.

Por ejemplo

que tenían un método similar a este que tenía 3 argumentos y que tenía que llamarlo desde performSelector -

-(void)getAllDetailsForObjectId:(NSString*)objId segment:(Segment*)segment inContext:(NSManagedObjectContext*)context{ 

me cambió este método para hacer uso de un diccionario para almacenar el argumentos

-(void)getAllDetailsForObject:(NSDictionary*)details{ 

por lo tanto, yo era capaz de llamar al método fácilmente

[self performSelector:@selector(getAllDetailsForObject:) withObject:@{Your info stored within a dictionary}]; 

Pensé que sería mejor compartir esto como una opción alternativa, ya que funciona para mí.

Saludos

Cuestiones relacionadas