使用SEL作为第二个参数调用动态添加的方法时EXEC_BAD_ACCESS

时间:2015-06-10 12:18:43

标签: objective-c

所以我尝试动态地向类中添加一个方法。该方法的IMP用块

构建
typedef void (^newMethodBlockType)(id, SEL, id);

newMethodBlockType newMethodBlock =  ^void(id _self, SEL _cmd, id newVal){
    // do something
};

IMP newMethodImp = imp_implementationWithBlock(newMethodBlock);

NSString *methodName = @"newMethod:";
SEL       newMethodSel = NSSelectorFromString(methodName);

Class clz = objc_getClass("MyClass");

class_addMethod(clz, newMethodSel, newMethodImp, "v@:@");

对class_addMethod的调用返回时没有错误。但是当我调用新方法时,我得到一个EXC_BAD_ACCESS错误,调试器将我带到声明块的行。

我认为由于某种原因,该块不会被保留。

添加:

newMethodBlock = [newMethodBlock copy];

似乎没有帮助。

编辑: 我设法通过将块的声明更改为不包括选择器作为第二个参数来使其工作。

newMethodBlockType newMethodBlock =  ^void(id _self, id newVal){
    // do something
};

现在似乎工作正常,但为什么呢? 并不总是将选择器发送到方法。

此方法用作属性的setter,并由

调用
[task setValue:[NSNumber numberWithLong:1001] forKey:@"myProperty"];

当通过setValue调用setter时:forKey:选择器是否未被发送到setter方法?

1 个答案:

答案 0 :(得分:0)

来自documentation for imp_implementationWithBlock()

  

block的签名应为method_return_type ^(id self, self, method_args …)block无法使用该方法的选择器。

我实际上认为第二个self在文档中是错误的,但很明显缺少_cmd