调用时非常方便,计算时间用了私有API
在.m文件中
#import "testTime.h"
#import <objc/runtime.h>
typedef void(^callback)(id result);
typedef void (*_VIMP) (id, SEL, ...);
typedef id(*_IMP) (id, SEL, ...);
static size_t const iterations = 100;
extern uint64_t dispatch_benchmark(size_t count, void (^block)(void));
@implementation testTime
void invokeMethodNoRetForEffctive(id target, SEL action, ...){
Method m1 = class_getInstanceMethod([target class], action);
int numberOfArguments = method_getNumberOfArguments(m1);
NSMutableArray *arr = [[NSMutableArray alloc] init];
va_list params;
id argument;
va_start(params, action);
while ((argument = va_arg(params, id))) {
[arr addObject:argument];
}
va_end(params);
_VIMP someMethod = (_VIMP)method_getImplementation(m1);
uint64_t t_1 = dispatch_benchmark(iterations, ^{
switch (numberOfArguments) {
case 2:
someMethod(target,action);
break;
case 3:
someMethod(target,action,arr[0]);
break;
case 4:
someMethod(target,action,arr[0],arr[1]);
break;
case 5:
someMethod(target,action,arr[0],arr[1],arr[2]);
break;
case 6:
someMethod(target,action,arr[0],arr[1],arr[2],arr[3]);
break;
case 7:
someMethod(target,action,arr[0],arr[1],arr[2],arr[3],arr[4]);
break;
default:
break;
}
});
NSLog(@"该方法总共耗时:--》 %llu ns",t_1);
}
void invokeMethodHasRetForEffctive(id target, SEL action, ...){
Method m1 = class_getInstanceMethod([target class], action);
int numberOfArguments = method_getNumberOfArguments(m1);
NSMutableArray *arr = [[NSMutableArray alloc] init];
va_list params;
id argument;
va_start(params, action);
while ((argument = va_arg(params, id))) {
[arr addObject:argument];
}
va_end(params);
_IMP someMethod = (_IMP)method_getImplementation(m1);
uint64_t t_1 = dispatch_benchmark(iterations, ^{
switch (numberOfArguments) {
case 2:
someMethod(target,action);
break;
case 3:
someMethod(target,action,arr[0]);
break;
case 4:
someMethod(target,action,arr[0],arr[1]);
break;
case 5:
someMethod(target,action,arr[0],arr[1],arr[2]);
break;
case 6:
someMethod(target,action,arr[0],arr[1],arr[2],arr[3]);
break;
case 7:
someMethod(target,action,arr[0],arr[1],arr[2],arr[3],arr[4]);
break;
default:
break;
}
});
NSLog(@"该方法总共耗时:--》 %llu ns",t_1);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
getMethodArgType(target, @selector(todoSomething:with:), 111, YES);
#pragma clang diagnostic pop
}
void getMethodArgType(id target, SEL action, ...){
NSMutableArray *argList = [[NSMutableArray alloc] init];
NSMethodSignature * methodSignature = [[target class] instanceMethodSignatureForSelector:action];
va_list params;
va_start(params, action);
for (int i=2; i<[methodSignature numberOfArguments]; i++) {
const char *argumentType = [methodSignature getArgumentTypeAtIndex:i];
switch(argumentType[0] == 'r' ? argumentType[1] : argumentType[0]) {
#define JP_FWD_ARG_CASE(_typeChar, _type) \
case _typeChar: { \
_type arg; \
arg = va_arg(params, _type); \
[argList addObject:@(arg)]; \
break; \
}
JP_FWD_ARG_CASE('c', int)
JP_FWD_ARG_CASE('C', unsigned int)
JP_FWD_ARG_CASE('s', int)
JP_FWD_ARG_CASE('S', unsigned int)
JP_FWD_ARG_CASE('i', int)
JP_FWD_ARG_CASE('I', unsigned int)
JP_FWD_ARG_CASE('l', long)
JP_FWD_ARG_CASE('L', unsigned long)
JP_FWD_ARG_CASE('q', long long)
JP_FWD_ARG_CASE('Q', unsigned long long)
JP_FWD_ARG_CASE('f', double)
JP_FWD_ARG_CASE('d', double)
JP_FWD_ARG_CASE('B', int)
default: {
id argument;
(argument = va_arg(params, id));
[argList addObject:argument];
break;
}
}
}
va_end(params);
NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:target];
[invocation setSelector:action];
for (int i=2; i<[methodSignature numberOfArguments]; i++) {
const char *argumentType = [methodSignature getArgumentTypeAtIndex:i];
switch(argumentType[0] == 'r' ? argumentType[1] : argumentType[0]) {
#define YH_SET_ARG_CASE(_typeChar, _type, _typeValue) \
case _typeChar: { \
_type argg = [argList[i-2] _typeValue]; \
[invocation setArgument:&argg atIndex:i]; \
break; \
}
YH_SET_ARG_CASE('c', char, charValue)
YH_SET_ARG_CASE('C', unsigned char, unsignedCharValue)
YH_SET_ARG_CASE('s', short, shortValue)
YH_SET_ARG_CASE('S', unsigned short, unsignedShortValue)
YH_SET_ARG_CASE('i', int, intValue)
YH_SET_ARG_CASE('I', unsigned int, unsignedIntValue)
YH_SET_ARG_CASE('l', long, longValue)
YH_SET_ARG_CASE('L', unsigned long, unsignedLongValue)
YH_SET_ARG_CASE('q', long long, longLongValue)
YH_SET_ARG_CASE('Q', unsigned long long, unsignedLongLongValue)
YH_SET_ARG_CASE('f', float, floatValue)
YH_SET_ARG_CASE('d', double, doubleValue)
YH_SET_ARG_CASE('B', BOOL, boolValue)
default: {
id argument =argList[i-2];
[invocation setArgument:&argument atIndex:i];
break;
}
}
}
uint64_t t_1 = dispatch_benchmark(iterations, ^{
[invocation invoke];
});
NSLog(@"该方法总共耗时:--》 %llu ns",t_1);
}
@end
然后在.h文件中声明函数
void invokeMethodNoRetForEffctive(id target, SEL action, ...);
void invokeMethodHasRetForEffctive(id target, SEL action, ...);
void getMethodArgType(id target, SEL action, ...);
然后在其他地方调用
invokeMethodNoRetForEffctive(self, @selector(insertObj:lala:), @"qwerq",@"111111", nil);
invokeMethodHasRetForEffctive(self, @selector(frc:lala:), @"qwerq",@"111111", nil);
callback call= ^(id result){
NSLog(@"111--callback");
};
@selector(frc:lala:), @"qwerq",call, nil);