I am trying to get parameters at runtime from some random method that is being called in my class. Before arm64(in armv7and armv7s) this can be done using the following code:
@interface MyClass
- (id)methodWithFirstParameter:(id)firstParam secondParameter:(id)secondParam;
@end
@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)sel {
[self addDynamicCallForSelector:sel];
return YES;
}
+ (void)addDynamicCallForSelector:(const SEL)selector {
const char *encoding;
IMP implementation;
implementation = [self instanceMethodForSelector:@selector(dynamicMethod:)];
Method newMethod = class_getInstanceMethod([self class], @selector(dynamicMethod:));
encoding = method_getTypeEncoding(newMethod);
class_addMethod([self class], selector, implementation, encoding);
}
- (id)dynamicMethod:(id)obj1, ... {
int parameterCount = [[NSStringFromSelector(_cmd) componentsSeparatedByString:@":"] count] - 1;
NSMutableArray *parameterList = [[NSMutableArray alloc] initWithCapacity:parameterCount];
va_list arguments;
va_start(arguments, obj1);
for (int i = 0; i < parameterCount; i++) {
id parameter = (i == 0) ? obj1 : va_arg(arguments, id);
if (!parameter) {
parameter = [NSNull null];
}
[parameterList addObject:parameter];
}
va_end(arguments);
return parameterList;
}
It is quite easy and clean. We simply pass all incoming calls to one single implementation, which can collect parameters from it and return them.
In arm64yet va_listit works well, but in this context of the first parameter va_arg(arguments, id)is the current instance of the class ( self). After the second call, he stopped with help EXC_BAD_ACCESS. Therefore, I think that he did not even find the first parameter (c va_start(arguments, obj1)).
, va_list arm64 , dynamicMethod: ( ). , - ( arm64, ).
, - .