Last active
August 22, 2017 22:03
-
-
Save byss/0aeaed30c2a0ddb0822e8c1595fb062b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
@interface NSInvocation (blah) | |
+ (NSInvocation *) invocationWithTarget:(id)target selector:(SEL)selector arguments:(void *)firstArgument, ... NS_REQUIRES_NIL_TERMINATION; | |
+ (NSInvocation *) undoInvocationWithTarget:(id)target selector:(SEL)selector arguments:(void *)firstArgument, ... NS_REQUIRES_NIL_TERMINATION; | |
@end | |
static NSUInteger const ARArgumentsListInvocationFirstArgumentIndex = 2; | |
@implementation NSInvocation (blah) | |
+ (NSInvocation *)invocationWithTarget:(id)target selector:(SEL)selector arguments:(void *)firstArgument, ... { | |
void *argument = firstArgument; | |
va_list argumentsList; | |
va_start (argumentsList, firstArgument); | |
NSInvocation *result = [self invocationWithTarget:target selector:selector firstArgument:argument argumentsList:argumentsList]; | |
va_end (argumentsList); | |
return result; | |
} | |
+ (NSInvocation *) undoInvocationWithTarget:(id)target selector:(SEL)selector arguments:(void *)firstArgument, ... { | |
void *argument = firstArgument; | |
va_list argumentsList; | |
va_start (argumentsList, firstArgument); | |
NSInvocation *result = [self invocationWithTarget:target selector:selector firstArgument:argument argumentsList:argumentsList]; | |
va_end (argumentsList); | |
return result; | |
} | |
+ (NSInvocation *)invocationWithTarget:(id)target selector:(SEL)selector firstArgument: (void *) argument argumentsList:(va_list) args { | |
NSMethodSignature *methodSignature = [target methodSignatureForSelector:selector]; | |
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; | |
invocation.target = target; | |
invocation.selector = selector; | |
NSUInteger index = ARArgumentsListInvocationFirstArgumentIndex; | |
while (argument) { | |
NSString *assertDescription = [NSString stringWithFormat:@"Превышено допустимое количество аргументов (%zd из %zd возможных)", (index - ARArgumentsListInvocationFirstArgumentIndex + 1), (methodSignature.numberOfArguments - ARArgumentsListInvocationFirstArgumentIndex)]; | |
NSAssert((index < methodSignature.numberOfArguments), assertDescription); | |
[invocation setArgument:argument atIndex:index]; | |
index++; | |
argument = va_arg (args, void *); | |
} | |
return invocation; | |
} | |
@end | |
@interface SomeClass: NSObject | |
- (void) doSomething: (NSString *) arg1 withArg: (int) arg2 boolArg: (BOOL) arg3 shitCunt: (NSArray *) arg4; | |
@end | |
int main (void) { | |
SomeClass *obj = [SomeClass new]; | |
NSString *str = @"lol"; | |
int i = 123; | |
BOOL b = YES; | |
NSArray *arr = @[@"ROOSTER"]; | |
NSInvocation *inv = [NSInvocation invocationWithTarget:obj selector:@selector (doSomething:withArg:boolArg:shitCunt:) arguments:&str, &i, &b, &arr, nil]; | |
[inv invoke]; | |
return 0; | |
} | |
@implementation SomeClass: NSObject | |
- (void) doSomething: (NSString *) arg1 withArg: (int) arg2 boolArg: (BOOL) arg3 shitCunt: (NSArray *) arg4 { | |
NSLog (@"%@ %d %d %@", arg1, arg2, arg3, arg4); | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment