Получить класс из экземпляра hex в Objective-C

Когда вы видите адрес переменной экземпляра в отладчике, как получить класс, введя его в указанный адрес памяти?

Я знаю, что обратное (получение адреса из экземпляра) возможно с p someObjectInstance в отладчике или NSLog(@"%p", someObjectInstance); из кода. Есть ли аналогичный способ сделать это наоборот?

Ответ 1

То, что вы просите, ОЧЕНЬ небезопасно. Доступ к неизвестному местоположению памяти, как правило, плохая идея, но поскольку вы спросили:

EDIT: Если внутри gdb или 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]);

Ответ 2

В отладчике вы можете использовать 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]. Это часто содержит более полезную информацию, которая просто имя класса (как видно из примера выше).

Как говорит Ричард Дж. Росс 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

Надеюсь, что это поможет.

Ответ 3

Щелкните правой кнопкой мыши в области отладки и выберите "Справка области отладки" → "Просмотр местоположений памяти"

Или в документации Xcode перейдите к

Библиотека разработчиков Xcode- > Xcode- > IDEs- > Справка по области отладки- > Просмотр местоположений памяти