Pregunta

si la variable en object_getIvar es un tipo de datos básico (por ejemplo, float, int, bool), ¿cómo obtengo el valor ya que la función devuelve un puntero (id) de acuerdo con la documentación? Intenté enviar a int, int * pero cuando trato de llevarlo a NSLog, recibo un error sobre un tipo de puntero incompatible.

¿Fue útil?

Solución

Obteniendo :

myFloat = 2.34f;

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

NSLog(@"%f", myFloatValue);

Salidas:

  

2.340000

Configuración :

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

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

NSLog(@"%f", myFloat);

Salidas:

  

2.340000

Otros consejos

Para ARC:

Inspirado por esta respuesta: object_getIvar no puede leer el valor de BOOL iVar . Debe emitir una llamada a la función object_getIvar para obtener ivars de tipo básico.

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

He creado una pequeña macro útil para la definición rápida de estos punteros de función:

#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;

Luego, para los tipos básicos, debe especificar las llamadas a macro (se ajustarán los parámetros, por ejemplo, (long long, LongLong)):

GET_IVAR_OF_TYPE_DEFININTION(int, Int)

Y después de eso, una función para recibir el tipo de variable int (o especificado) estará disponible:

int result = XYIntGetVariableFunction(object, variableName)

El valor que se devuelve es el valor del lugar correcto en el objeto; Simplemente no es el tipo correcto. Para int y BOOL (pero no para float ), puede lanzar el puntero a un int o BOOL , ya que los punteros y las entradas son del mismo tamaño y se pueden lanzar entre sí:

(int)object_getIvar(obj, myIntVar)

Probablemente esté encuadrando el valor en un NSNumber. Puede verificar esto haciendo NSLogging del className del ID devuelto, así:

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

Editar: Encontré otra pregunta como esta aquí: Manejo del valor de retorno de object_getIvar (objeto id, Ivar ivar)

De mi propia experimentación, parecería que mi suposición original era incorrecta. int y float y otras primitivas parecen ser devueltas como el valor real. Sin embargo, sería apropiado usar ivar_getTypeEncoding para verificar que el valor devuelto sea del tipo que espera que sea.

puede usar object_getInstanceVariable directamente: (no lo he probado)

void *ptr_to_result;
object_getInstanceVariable(obj, "intvarname", &ptr_to_result);
float result = *(float *)ptr_to_result;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top