2011-07-25 64 views
5

我想在Obj-c runtime reference添加方法动态

BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) 

我想补充像一个新的方法,发现这个方法:

- [AClass drawWithFrame:(NSRect)rect inView:(id)view] 

到目前为止,我已经写了一个C函数:

void drawWithFrameInView(id this, SEL this_cmd, NSRect frame, id view){ 
... 
} 

现在我准备好了:

BOOL success = class_addMethod(NSClassFromString(@"AClass"), 
           @selector(drawWithFrame:inView:), 
           (IMP)drawWithFrameInView, 
           "[email protected]:@:@:"); 

success从来没有是,我已经尝试了与更简单的签名方法相同的方法,它的工作。所以我认为问题是最后一个参数:"[email protected]:@:@:"

在这种情况下我应该通过什么来让我的新方法工作?

+0

为什么不命名前两个参数'self'和'_cmd',这样你就可以写出你在方法中写入的相同代码? –

+0

嗯......只是出于美学原因。从C的角度来看'self'和'_cmd'应该是正常的参数。我不喜欢在Obj-C中将参数着色为关键字的事实(即使它们代表这些关键字)。这是所有:) – nacho4d

回答

8

这将工作:

char *types = [[NSString stringWithFormat:@"[email protected]:%[email protected]", @encode(NSRect)] UTF8String]; 

BOOL success = class_addMethod(NSClassFromString(@"MyClass"), 
           @selector(drawWithFrame:inView:), 
           (IMP)drawWithFrameInView, 
           types); 

为什么你的代码不起作用的原因是因为NSRect不是对象,它是一个typedefstruct

了解有关类型编码的更多信息here

+0

这似乎工作(至少我得到了成功= YES :))。然而,文档说:*由于函数必须至少有两个参数-self和_cmd,所以第二个和第三个字符必须是“@:”(第一个字符是返回类型)*,而'types'不包含返回值类型,这是因为“无效”还是在这里有某种推论? – nacho4d

+0

@ nacho4d'types' ***确实包含一个返回类型 - 第一个元素是''v'','void'。 –

+0

谢谢!现在我看到'v'很清楚:) – nacho4d