method_getImplementation crashes on 64-bit iphone 5s

强颜欢笑 提交于 2019-12-10 11:57:49

问题


I have a piece of code in my project

- (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;
    }
}

Here's the call of first method:

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];

But it crashes at (showing no log):

return grannyImp([class_name class], selector, count, [class_name class]);

PS: It crashes when I include arm64 architecture to the project's Valid Architectures section. But when I leave this section without arm64 it runs without problem.

Is there any problematic code I done?


回答1:


There is problem with the keyword IMP.
Actually IMP defines a function with the prototype:id (*)(id, SEL, ...).

Under Arm64 passing arguments to a function with a variable argument count is different than how it is under Arm6 and 7

instead of IMP you should use exact prototype of your function.
Use this type:
typedef NSData* (*getIvarsFunction)(id, SEL, unsigned int*, Class);

And your code will be:

- (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]);
    }
}

This code will work on arm6,7,64.



来源:https://stackoverflow.com/questions/28942384/method-getimplementation-crashes-on-64-bit-iphone-5s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!