| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- //
- // RACBlockTrampoline.m
- // ReactiveCocoa
- //
- // Created by Josh Abernathy on 10/21/12.
- // Copyright (c) 2012 GitHub, Inc. All rights reserved.
- //
- #import "RACBlockTrampoline.h"
- #import "RACTuple.h"
- @interface RACBlockTrampoline ()
- @property (nonatomic, readonly, copy) id block;
- @end
- @implementation RACBlockTrampoline
- #pragma mark API
- - (id)initWithBlock:(id)block {
- self = [super init];
- if (self == nil) return nil;
- _block = [block copy];
- return self;
- }
- + (id)invokeBlock:(id)block withArguments:(RACTuple *)arguments {
- NSCParameterAssert(block != NULL);
- RACBlockTrampoline *trampoline = [[self alloc] initWithBlock:block];
- return [trampoline invokeWithArguments:arguments];
- }
- - (id)invokeWithArguments:(RACTuple *)arguments {
- SEL selector = [self selectorForArgumentCount:arguments.count];
- NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
- invocation.selector = selector;
- invocation.target = self;
- for (NSUInteger i = 0; i < arguments.count; i++) {
- id arg = arguments[i];
- NSInteger argIndex = (NSInteger)(i + 2);
- [invocation setArgument:&arg atIndex:argIndex];
- }
- [invocation invoke];
-
- __unsafe_unretained id returnVal;
- [invocation getReturnValue:&returnVal];
- return returnVal;
- }
- - (SEL)selectorForArgumentCount:(NSUInteger)count {
- NSCParameterAssert(count > 0);
- switch (count) {
- case 0: return NULL;
- case 1: return @selector(performWith:);
- case 2: return @selector(performWith::);
- case 3: return @selector(performWith:::);
- case 4: return @selector(performWith::::);
- case 5: return @selector(performWith:::::);
- case 6: return @selector(performWith::::::);
- case 7: return @selector(performWith:::::::);
- case 8: return @selector(performWith::::::::);
- case 9: return @selector(performWith:::::::::);
- case 10: return @selector(performWith::::::::::);
- case 11: return @selector(performWith:::::::::::);
- case 12: return @selector(performWith::::::::::::);
- case 13: return @selector(performWith:::::::::::::);
- case 14: return @selector(performWith::::::::::::::);
- case 15: return @selector(performWith:::::::::::::::);
- }
- NSCAssert(NO, @"The argument count is too damn high! Only blocks of up to 15 arguments are currently supported.");
- return NULL;
- }
- - (id)performWith:(id)obj1 {
- id (^block)(id) = self.block;
- return block(obj1);
- }
- - (id)performWith:(id)obj1 :(id)obj2 {
- id (^block)(id, id) = self.block;
- return block(obj1, obj2);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 {
- id (^block)(id, id, id) = self.block;
- return block(obj1, obj2, obj3);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 {
- id (^block)(id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 {
- id (^block)(id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 {
- id (^block)(id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 {
- id (^block)(id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 {
- id (^block)(id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 {
- id (^block)(id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 {
- id (^block)(id, id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 {
- id (^block)(id, id, id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 {
- id (^block)(id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 :(id)obj13 {
- id (^block)(id, id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 :(id)obj13 :(id)obj14 {
- id (^block)(id, id, id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13, obj14);
- }
- - (id)performWith:(id)obj1 :(id)obj2 :(id)obj3 :(id)obj4 :(id)obj5 :(id)obj6 :(id)obj7 :(id)obj8 :(id)obj9 :(id)obj10 :(id)obj11 :(id)obj12 :(id)obj13 :(id)obj14 :(id)obj15 {
- id (^block)(id, id, id, id, id, id, id, id, id, id, id, id, id, id, id) = self.block;
- return block(obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8, obj9, obj10, obj11, obj12, obj13, obj14, obj15);
- }
- @end
|