2011-07-25 65 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