当不涉及到用户隐私的时候,我们调用私有方法一般都没有什么问题。
在我们调用私有方法之前,我们必须要先知道你想调用的对象有哪些私有方法,和需要参数的那些方法的参数类型,和返回值的类型是多少。
查看私有方法名,参数类型和返回值类型
- (void)scanMethodsTwo:(Class)class {
unsigned int outCount = 0; // unsigned int :是无符号基本整型,没有负数
Method *methods = class_copyMethodList(class, &outCount); // 获取类的方法列表
for (int i = 0; i < outCount; i++) {
Method method = methods[i];
// 获取方法名
SEL sel = method_getName(methods[i]);
NSLog(@"方法名==== %@", NSStringFromSelector(sel));
// 获取参数
char argInfo[512] = {};
unsigned int argCount = method_getNumberOfArguments(method);
for (int j = 0; j < argCount; j++) {
// 参数类型
method_getArgumentType(method, j, argInfo, 512);
NSLog(@"参数类型=== %s", argInfo);
memset(argInfo, '\0', strlen(argInfo));
}
// 获取方法返回值类型
char retType[512] = {};
method_getReturnType(method, retType, 512);
NSLog(@"返回值类型=== %s", retType);
}
free(methods);
}
调用无参数方法
当知道方法名过后,我们调用没有参数的私有方法,有两种:
方法一:使用performSelector来调用
[button performSelector:@selector(updateConstraints)];
方法二:也可以使用objc_msgSend来调用,但是是有这个必须要导入#import <objc/runtime.h>,#import <objc/message.h>这两个头文件。
((void(*)(id,SEL))objc_msgSend)(button, @selector(updateConstraints));
如果要使用下面这种写法,必须要在项目配置文件 -> Build Settings -> Enable Strict Checking of objc_msgSend Calls 这个字段设置为 NO, 默认为YES.
objc_msgSend(button, @selector(updateConstraints));
调用有参数方法
要使用objc_msgSend来调用,并传递参数
((void(*)(id,SEL, CGRect))objc_msgSend)(button, @selector(setFrame:), CGRectMake(200, 100, 50, 50));
objc_msgSend(button, @selector(setFrame:), CGRectMake(200, 100, 50, 50));