method_getImplementation在64位iphone 5s上崩溃

Sha*_*din 0 xcode cocoa-touch objective-c ios arm64

我的项目中有一段代码

- (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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是第一种方法的调用:

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];
Run Code Online (Sandbox Code Playgroud)

但它崩溃了(显示没有日志):

return grannyImp([class_name class], selector, count, [class_name class]);
Run Code Online (Sandbox Code Playgroud)

PS:当我将arm64架构包含在项目的Valid Architectures部分时,它会崩溃.但是当我离开这个部分而没有arm64它运行没有问题.

我做的代码有问题吗?

在此输入图像描述

Cy-*_*4AH 6

关键字存在问题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]);
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码适用于arm6,7,64.