Skip to content

Instantly share code, notes, and snippets.

@miguel12345
Last active August 29, 2015 14:07
Show Gist options
  • Save miguel12345/d30301fce263ddbd46e4 to your computer and use it in GitHub Desktop.
Save miguel12345/d30301fce263ddbd46e4 to your computer and use it in GitHub Desktop.
Generic Currying in Objective-c
//The magic method
-(id (^)(id,...)) getSelector:(SEL) aSelector forTarget:(id) target withFirstArguments:(id) firstArguments, ... {
NSMutableArray* firstArgumentsArray = [NSMutableArray array];
va_list first_args;
va_start(first_args, firstArguments);
do
{
[firstArgumentsArray addObject:firstArguments];
}
while( (firstArguments = va_arg(first_args,id)) );
va_end(first_args);
id (^blockName)(id,...) = ^id(id values,...) {
SEL theSelector;
NSMethodSignature *aSignature;
NSInvocation *anInvocation;
theSelector = aSelector;
aSignature = [self methodSignatureForSelector:theSelector];
anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
[anInvocation setSelector:theSelector];
[anInvocation setTarget:self];
int index = 2;
for (id firstArgumentId in firstArgumentsArray) {
id coiso = firstArgumentId;
[anInvocation setArgument:&coiso atIndex:index++];
}
va_list args;
va_start(args, values);
id value = values;
do
{
[anInvocation setArgument:&value atIndex:index++];
}
while( (value = va_arg(args,id)));
va_end(args);
[anInvocation invoke];
id tempResult;
[anInvocation getReturnValue:&tempResult];
id result = tempResult;
return result;
};
return blockName;
}
//Example methods
-(id) sumA:(NSNumber*) a WithB:(NSNumber*) b {
return [NSNumber numberWithInt:([a intValue] + [b intValue])];
}
-(id) sumA:(NSNumber*) a WithB:(NSNumber*) b withC:(NSNumber*) c{
return [NSNumber numberWithInt:([a intValue] + [b intValue] + [c intValue])];
}
//Usage
id (^blockName)(id,...) = [self getSelector:@selector(sumA:WithB:) forTarget:self withFirstArguments:@2,nil];
NSLog(@"%@",blockName(@3,nil)); //Output: 5
blockName = [self getSelector:@selector(sumA:WithB:withC:) forTarget:self withFirstArguments:@2,nil];
NSLog(@"%@",blockName(@3,@4,nil)); //Output: 9
blockName = [self getSelector:@selector(sumA:WithB:withC:) forTarget:self withFirstArguments:@2,@5,nil];
NSLog(@"%@",blockName(@1,nil)); //Output: 8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment