我想要繼承某個類並覆蓋它的一些私有方法。這是危險的,可能會失敗,無法通過蘋果的審查(在AppStore),可能會有可怕的影響等,但這只是爲了實驗/教育的目的:)在方法中獲取參數類型
例如,讓我們說我想知道類型實例方法UITextView
keyboardInput:shouldInsertText:isMarkedText:
的第一個參數:
SEL selector = @selector(keyboardInput:shouldInsertText:isMarkedText:);
Class class = [UITextView class];
Method method = class_getInstanceMethod(class, selector);
char *arg = method_copyArgumentType(method, 0);
printf("_%s_\n", arg);
free(arg);
但是在控制檯中我只得到[email protected]_
。 我認爲@
意味着對象但什麼類的對象? (我想我會得到參數類的名稱)是否有可能使用其他objective-c runtime functions或其他任何意思得到該參數的類? PS:在這個例子中,我使用了一類可可觸摸,但我可以嘗試與一類可可完全相同。所以這不應該特定於iOS。
解決:
我在戴夫建議模擬器嘗試,它的工作!
(gdb) info all-registers
給了我價值的一個長長的清單,...
((gdb) po *(id*)($ebp + 8)
<MyTextView: 0x5911270; baseClass = UITextView; frame = (80 70; 240 323); text = 'Lorem ipsum dolor sit er ...'; clipsToBounds = YES; autoresize = RM+BM; layer = <CALayer: 0x5c0c7d0>; contentOffset: {0, 0}>
(gdb) p *(SEL*)($ebp + 12)
$5 = (SEL) 0xbd19
(gdb) po *(id*)($ebp + 16)
<UIWebDocumentView: 0xa02f000; frame = (0 0; 240 457); text = 'Lorem ipsum dolor sit er ...'; opaque = NO; userInteractionEnabled = NO; layer = <UIWebLayer: 0x5c35070>>
(gdb) po *(id*)($ebp + 20)
t
(gdb) p *(id*)($ebp + 24)
$6 = (id) 0x0
這是有道理的,因爲我按下的鍵是一個「T」,所以它沒有標註文字(「爲0x0」),所以我可以認爲第一個參數應該是UIWebDocumentView
。
只是一件小事(在這種情況下無關緊要),我怎麼能從gbd的SEL中獲得方法名?例如$5
?
'SEL' *是方法名稱。使用'sel_getName'函數將選擇器作爲C字符串;另請參閱http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/。還有'NSStringFromSelector',它完全按照它所說的,是基礎的一部分(並且記錄在其中)。 –