在Objective-C中,如何从实例的十六进制值获取类?

13

当在调试器中查看实例变量的地址时,如何通过输入给定的内存地址获取类?

我知道相反的情况(从实例获取地址)可以使用调试器中的p someObjectInstance或代码中的NSLog(@"%p", someObjectInstance);。有没有类似的方法来做到这一点?

4个回答

25
您所要求的做法非常不安全。访问未知的内存位置通常是一个坏主意,但既然您要求了:
编辑:如果在 gdblldb 中,则可以执行以下操作:
po [(id)(0xDEADBEEF) class]

如果是从代码中运行,请使用以下内容:
NSString *input = @"0xFAFAFA";

unsigned address = UINT_MAX; // or UINT_MAX
[[NSScanner scannerWithString:input] scanHexInt:&address];

if (address == UINT_MAX)
{
    // couldn't parse input...
    NSLog(@"failed to parse input");
    return 0;
}

void *asRawPointer = (void *) (intptr_t) address;
id value = (__bridge id) asRawPointer;

// now do something with 'value'
NSLog(@"%@", [value class]);

谢谢。我同意这是非常不安全的!我只是想把它加入调试工具库中。 ;) - Old McStopher

4

在调试器中,您可以对您怀疑是有效的Objective-C对象的地址使用po。例如,在我的程序运行中,我知道0x9549ee0指向一个UIFont对象。

使用po,我看到以下内容:

(gdb) po 0x9549ee0
<UICFFont: 0x9549ee0> font-family: "Helvetica"; font-weight: normal; font-style: normal; font-size: 14px

这将打印出您使用以下方式获得的相同信息:

NSLog(@"%@", someObject);

即是指[someObject description]的结果。通常这个结果包含比仅仅类名更有用的信息(正如上面的例子所示)。

正如Richard J. Ross III所提到的,你需要小心使用这种方法。调试器通常可以判断地址是否无效,例如:

(gdb) po 0x9449ee0
0x9449ee0 does not appear to point to a valid object.

但是它的实现并不是绝对可靠的。如果你在程序中使用代码来实现,很可能会导致程序崩溃。

当然,你也可以直接在变量上使用po命令:

(gdb) po font
<UICFFont: 0x9549ee0> font-family: "Helvetica"; font-weight: normal; font-style: normal; font-size: 14px

希望这能帮到你。

1

在调试区域中右键单击,然后选择“调试区域帮助” -> “查看内存位置”

或者在Xcode文档中转到

Xcode开发人员库 -> Xcode -> IDEs -> 调试区域帮助 -> 查看内存位置


这是用于查看对象的十六进制转储。它不会告诉你它是什么类(或者至少,这样做的路线过于复杂)。 - Peter Hosey

0
在 Swift 中,您可以使用 unsafeBitCast
(lldb) e let $vc = unsafeBitCast(0x7fd0b3e22bc0, GooglyPuff.PhotoCollectionViewController.self)
(lldb) po $vc.navigationItem.prompt = "WOOT!"

Swift Grand Central Dispatch教程:第2/2部分阅读


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接