nac*_*o4d 5 iphone cocoa objective-c
我试图子类化某个类并覆盖它的一些私有方法.这很危险,可能会失败,无法通过Apple的评论(在AppStore中),可能会产生可怕的影响等,但这只是为了实验/教育目的:)
例如,假设我想知道实例方法keyboardInput:shouldInsertText:isMarkedText:的第一个参数的类型UITextView:
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);
Run Code Online (Sandbox Code Playgroud)
但是在控制台中我只能得到_@_.我认为@意味着对象而不是什么类的对象?(我以为我会得到参数类的名称)是否有可能使用其他Objective-c运行时函数或任何其他方法获取该参数的类?
PS:在这个例子中,我使用了一类Cocoa touch,但我可以尝试使用一类Cocoa完全相同.所以这不应该是针对iOS的.
解决了:
我在模拟器中尝试了Dave的建议,它有效!
(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
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为我按下的键是单个"t"所以它没有标记文本("0x0")所以我可以认为第一个参数应该是类型UIWebDocumentView.
只是一件小事(在这种情况下无关紧要),我如何从gbd中的SEL获取方法名称?比如$5?
你不能从界面的内省中告诉类的参数.id一旦编译完成,所有在Objective-C中都是相同的.但是,您可以询问具体的实例-class.因此,如果您正在尝试对内部方法进行反向工程,则需要调整方法,调用它,然后内省您传递的对象.关于如何将代码注入任何Objective-C方法的大量讨论,谷歌"方法调整".
假设这是对学术的兴趣只 ....
您可以找到的一种方法是打破GDB中的符号并检查参数.你知道一般他们是那种(即,floatVS object等),所以你可以简单地使用正确的p命令来打印.
要设置断点,您可以执行以下操作:
b -[UITextView keyboardInput:shouldInsertText:isMarkedText:]-[UITextView keyboardInput:shouldInsertText:isMarkedText:]当你真正达到断点时,你不会看到任何有用的东西(当然).但是你可以在这一点上打印出这些参数,因为你知道它们的大小,以及它们应该在寄存器中的位置.
有关他们所在的寄存器的更多信息,请查看这篇方便的博客文章.您还可以执行类似info all-registers打印所有寄存器等所有信息的操作.
更新
如果你想打印选择器的名称,你可以使用一个小技巧,即选择器或多或少*char*s:
p (char*)$5
Run Code Online (Sandbox Code Playgroud)
将打印:
${some number} = 0x{some address} "keyboardInput:shouldInsertText:isMarkedText:"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1489 次 |
| 最近记录: |