Skip to content

Instantly share code, notes, and snippets.

@bsneed
Created August 3, 2010 23:15
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bsneed/507344 to your computer and use it in GitHub Desktop.
Save bsneed/507344 to your computer and use it in GitHub Desktop.
performSelector reimplementation with variable number of params/types and return type.
/*
You can use this to call deprecated methods without warnings (supporting old sdk's for example)
or, you can use it in place of performSelector: where you need non-object params, or multiple
params.
ie: ...
int result = 0;
int index = 12;
NSArray *array = myArray;
result = [self performSelector:@selector(checkSomething:atIndex:) returnAddress:&result argumentAddresses:&array, &index];
*/
- (void)performSelector:(SEL)aSelector returnAddress:(void *)result argumentAddresses:(void *)arg1, ...
{
va_list args;
va_start(args, arg1);
if([self respondsToSelector:aSelector])
{
NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:aSelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: methodSig];
[invocation setTarget:self];
[invocation setSelector:aSelector];
if (arg1)
[invocation setArgument:arg1 atIndex:2];
void *theArg = nil;
for (int i = 3; i < [methodSig numberOfArguments]; i++)
{
theArg = va_arg(args, void *);
if (theArg)
[invocation setArgument:theArg atIndex:i];
}
[invocation invoke];
if (result)
[invocation getReturnValue:result];
}
va_end(args);
}
@bsneed
Copy link
Author

bsneed commented Aug 13, 2010

just fixed a misplaced &. get le new one.

@soffes
Copy link

soffes commented Oct 6, 2012

Wouldn't setting result = ... give a warning since it's a void method? I realize that's the point of passing it by reference to returnAddress, but setting it when called seems like a typo. I may be way off. I'd love an explanation either way :)

@bsneed
Copy link
Author

bsneed commented Nov 1, 2012

sorry, missed this.

not sure i follow. if result is nil when passed in, it's not going to try and set it post invoke. if you give a return value and the selector's return is void, then yes, you may see problems.

though, now that i'm looking at the return a little more.. it is assuming result's size, which i should fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment