Как получить значение int из object_getIvar(self, myIntVar), поскольку оно возвращает указатель

StackOverflow https://stackoverflow.com/questions/1217139

Вопрос

если переменная в object_getIvar имеет базовый тип данных (например.float, int, bool) как мне получить значение, поскольку функция возвращает указатель (id) согласно документации.Я пробовал выполнить приведение к int, int*, но когда я пытаюсь передать это в NSLog, я получаю сообщение об ошибке о несовместимом типе указателя.

Это было полезно?

Решение

Получающий:

myFloat = 2.34f;

float myFloatValue;
object_getInstanceVariable(self, "myFloat", (void*)&myFloatValue);

NSLog(@"%f", myFloatValue);

Выходы:

2.340000

Параметр:

float newValue = 2.34f;
unsigned int addr = (unsigned int)&newValue;

object_setInstanceVariable(self, "myFloat", *(float**)addr);

NSLog(@"%f", myFloat);

Выходы:

2.340000

Другие советы

Для ARC:

Вдохновленный этим ответом: object_getIvar не удается прочитать значение BOOL iVar . Вы должны вызвать вызов функции для object_getIvar, чтобы получить ivars базового типа.

typedef int (*XYIntGetVariableFunction)(id object, const char* variableName);
XYIntGetVariableFunction intVariableFunction = (XYIntGetVariableFunction)object_getIvar;
int result = intVariableFunction(object, intVarName);

Я сделал небольшой полезный макрос для быстрого определения таких указателей на функции:

#define GET_IVAR_OF_TYPE_DEFININTION(type, capitalized_type) \
typedef type (*XY ## capitalized_type ## GetVariableFunctionType)(id object, Ivar ivar); \
XY ## capitalized_type ## GetVariableFunctionType XY ## capitalized_type ## GetVariableFunction = (XY ## capitalized_type ## GetVariableFunctionType)object_getIvar;

Затем для базовых типов необходимо указать обращения к макросу (например, параметры (long long, LongLong) подойдут):

GET_IVAR_OF_TYPE_DEFININTION(int, Int)

И после этого становится доступной функция для получения типа переменной int (или указанного):

int result = XYIntGetVariableFunction(object, variableName)

Возвращаемое значение - это значение из правильного места в объекте; просто не тот тип. Для int и BOOL (но не float ) вы можете просто привести указатель к int или BOOL , поскольку указатели и целые числа имеют одинаковый размер и их можно приводить друг к другу:

(int)object_getIvar(obj, myIntVar)

Это, вероятно, бокс в значении в NSNumber. Вы можете проверить это с помощью NSLogging возвращенного идентификатора className, например, так:

id returnedValue = object_getIvar(self, myIntVar);
NSLog(@"Class: %@", [returnedValue className]);

Изменить: я нашел еще один вопрос, такой же, как этот, здесь: Обработка возвращаемого значения object_getIvar (объект id, Ivar ivar)

Из моих собственных экспериментов оказалось, что мое первоначальное предположение было неверным. int и float и другие примитивы, по-видимому, возвращаются как фактические значения. Однако было бы целесообразно использовать ivar_getTypeEncoding, чтобы убедиться, что возвращаемое значение соответствует ожидаемому типу.

вы можете использовать object_getInstanceVariable напрямую: (еще не проверял)

void *ptr_to_result;
object_getInstanceVariable(obj, "intvarname", &ptr_to_result);
float result = *(float *)ptr_to_result;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top