13

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

我知道p someObjectInstance在调试器中或NSLog(@"%p", someObjectInstance);从代码中可能会出现相反的情况(从实例中获取地址)。有没有类似的方法可以反过来做呢?

4

4 回答 4

24

你要求的是非常不安全的。访问未知的内存位置通常是一个坏主意,但既然你问了:

编辑:如果在内部gdbor lldb,您可以执行以下操作:

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]);
于 2012-07-13T01:07:06.530 回答
4

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

使用po我看到以下内容:

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

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

NSLog(@"%@", someObject);

也就是 的结果[someObject description]。这通常包含更多有用的信息,而不仅仅是类名(从上面的示例可以看出)。

正如理查德 J. 罗斯三世所说,你应该小心这样做。调试器通常可以判断地址是否无效,例如:

(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

希望这可以帮助。

于 2012-07-13T01:24:21.343 回答
1

右键单击调试区域并选择调试区域帮助->查看内存位置

或者在 Xcode 文档中转到

Xcode Developer Library->Xcode->IDEs->Debug Area Help->查看内存位置

于 2012-11-12T18:09:44.957 回答
0

在 Swift 中,您可以使用unsafeBitCast

(lldb) e let $vc = unsafeBitCast(0x7fd0b3e22bc0, GooglyPuff.PhotoCollectionViewController.self)
(lldb) po $vc.navigationItem.prompt = "WOOT!"

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

于 2016-01-15T04:43:28.043 回答