method_getImplementation 在 64 位上崩溃 iphone 5 秒
method_getImplementation crashes on 64-bit iphone 5s
我的项目中有一段代码
- (NSData *)getIvars:(unsigned int *)count from:(id)class_name NS_RETURNS_RETAINED {
@synchronized(self) {
SEL selector = @selector(copyIvarList:from:);
Method grannyMethod = class_getInstanceMethod([class_name class], selector);
IMP grannyImp = method_getImplementation(grannyMethod);
return grannyImp([class_name class], selector, count, [class_name class]);
}
}
- (NSData *)copyIvarList:(unsigned int *)count from:(id)class_name NS_RETURNS_RETAINED {
@synchronized(self) {
Ivar *ret_val_c = class_copyIvarList([class_name class], count);
NSData *ret_val = [[NSData alloc] initWithBytes:ret_val_c length:sizeof(Ivar) * *count];
free(ret_val_c);
return ret_val;
}
}
这里是第一个方法的调用:
Class class_to_anylize = [self superclass]; // some class inherieted from NSObject
unsigned int ivar_count = 0;
NSData *new_var_list = [self getIvars:&ivar_count from:class_to_anylize];
但它崩溃了(没有显示日志):
return grannyImp([class_name class], selector, count, [class_name class]);
PS: 当我将 arm64
架构包含到项目的 Valid Architectures 部分时它崩溃了。但是当我离开这个部分时没有 arm64
它运行没有问题。
我做的代码有问题吗?
关键字 IMP
有问题。
实际上IMP
定义了一个函数,原型为:id (*)(id, SEL, ...)
.
在 Arm64 下向具有可变参数计数的函数传递参数与在 Arm6 和 7 下不同
而不是 IMP
你应该使用你的函数的精确原型。
使用此类型:
typedef NSData* (*getIvarsFunction)(id, SEL, unsigned int*, Class);
您的代码将是:
- (NSData *)getIvars:(unsigned int *)count from:(id)class_name NS_RETURNS_RETAINED {
@synchronized(self) {
SEL selector = @selector(copyIvarList:from:);
Method grannyMethod = class_getInstanceMethod([class_name class], selector);
getIvarsFunction grannyImp = (getIvarsFunction)method_getImplementation(grannyMethod);
return grannyImp([class_name class], selector, count, [class_name class]);
}
}
此代码适用于 arm6、7、64。
我的项目中有一段代码
- (NSData *)getIvars:(unsigned int *)count from:(id)class_name NS_RETURNS_RETAINED {
@synchronized(self) {
SEL selector = @selector(copyIvarList:from:);
Method grannyMethod = class_getInstanceMethod([class_name class], selector);
IMP grannyImp = method_getImplementation(grannyMethod);
return grannyImp([class_name class], selector, count, [class_name class]);
}
}
- (NSData *)copyIvarList:(unsigned int *)count from:(id)class_name NS_RETURNS_RETAINED {
@synchronized(self) {
Ivar *ret_val_c = class_copyIvarList([class_name class], count);
NSData *ret_val = [[NSData alloc] initWithBytes:ret_val_c length:sizeof(Ivar) * *count];
free(ret_val_c);
return ret_val;
}
}
这里是第一个方法的调用:
Class class_to_anylize = [self superclass]; // some class inherieted from NSObject
unsigned int ivar_count = 0;
NSData *new_var_list = [self getIvars:&ivar_count from:class_to_anylize];
但它崩溃了(没有显示日志):
return grannyImp([class_name class], selector, count, [class_name class]);
PS: 当我将 arm64
架构包含到项目的 Valid Architectures 部分时它崩溃了。但是当我离开这个部分时没有 arm64
它运行没有问题。
我做的代码有问题吗?
关键字 IMP
有问题。
实际上IMP
定义了一个函数,原型为:id (*)(id, SEL, ...)
.
在 Arm64 下向具有可变参数计数的函数传递参数与在 Arm6 和 7 下不同
而不是 IMP
你应该使用你的函数的精确原型。
使用此类型:
typedef NSData* (*getIvarsFunction)(id, SEL, unsigned int*, Class);
您的代码将是:
- (NSData *)getIvars:(unsigned int *)count from:(id)class_name NS_RETURNS_RETAINED {
@synchronized(self) {
SEL selector = @selector(copyIvarList:from:);
Method grannyMethod = class_getInstanceMethod([class_name class], selector);
getIvarsFunction grannyImp = (getIvarsFunction)method_getImplementation(grannyMethod);
return grannyImp([class_name class], selector, count, [class_name class]);
}
}
此代码适用于 arm6、7、64。