How can I perform an obj-c message with a selector and variable number parameters? [duplicate]

StackOverflow https://stackoverflow.com/questions/22162651

  •  19-10-2022
  •  | 
  •  

Domanda

Is there any method like this:

- (id)performSelector:(SEL)selector withParameters:(NSArray *)parameters;

and I can invoke a obj-c message like this:

// invoke a message with 3 parameters
[obj performSelector:@selector(evaluate:name:animate:) withParameters:@[@1, @"test", @YES]];

// invoke a message with 1 parameter which is an array containing 3 components.
[NSArray performSelector:@selector(arrayWithArray:) withParameters:@[@[@1, @"test", @YES]]];

If there is no such method like this. How can I implement this with Obj-C runtime? Is it impossible?

È stato utile?

Soluzione

Use NSInvocation

- (id)performSelector:(SEL)selector withParameters:(NSArray *)parameters
{
    NSMethodSignature *signature  = [self methodSignatureForSelector:selector];
    NSInvocation      *invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setTarget:self];       
    [invocation setSelector:selector];            
    for (int i = 0; i < parameters.count; ++i)
    {
        id para = parameters[i];
        [invocation setArgument:&para atIndex:2+i];  
    }

    [invocation invoke];

    id ret;
    [invocation getReturnValue:&ret];
    return ret;

}

Note: this implementation only works if the invoked method takes ObjC objects as arguments and return an object. i.e. it won't work for something takes int or return double.

If you want it works for primitive types/struct, you have to check NSMethodSignature for arguments type and convert object to that type then pass it to setArgument:atIndex:.

Read this question for more detailed ansowers

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top