Pregunta

object_getIvar(objeto de identificación, Ivar ivar) lee los valores de iVArs correctamente pero falla en un iVar de tipo BOOL y falla.Necesito los valores de todas las iVars de una clase. ¿Hay alguna forma de resolverlo?

¿Fue útil?

Solución

object_getIvar parece devolver el valor real (no una identificación) que está en oposición a lo que dice el manual.Si está utilizando ARC, esto provocará una falla inmediata del procesador durante el intento de retener el valor devuelto que no es un objeto.

object_getInstanceVariable () devuelve un puntero a la información, pero ARC se niega a aceptar la función.

Otros consejos

Accediendo directamente a ivars poder realizarse mediante ARC.Puede acceder tanto a tipos básicos de C (char, short, int, etc.) como a objetos Objective-C.Por ejemplo, un unsigned char Se puede acceder a ivar utilizando el siguiente patrón.Reemplazar el nombre del tipo con otros tipos básicos genera un descriptor de acceso para ese tipo de ivar.

unsigned char val;

val = ((unsigned char (*)(id, Ivar))object_getIvar)(object, ivar);

NSLog(@"Looks like I got: %u (or character %c)", val, val);

Detrás de escena, estás empleando algunas travesuras para engañar al compilador haciéndole creer que object_getIvar() es en realidad una función que devuelve el tipo que busca.Este tipo de elenco cambios la forma en que el compilador llama e interpreta el resultado de object_getIvar, y es necesario porque los tipos básicos de C pueden tener un tamaño de 8 a 64 bits y solo el compilador sabe cómo se manejan cuando se usan como valores de retorno, lo cual está definido por el ABI utilizado por la arquitectura para la que está compilando.

Sí, parece gracioso, pero es la forma más portátil de hacerlo y, bueno, simplemente funciona.:-) Usar un yeso tipo recto no funcionará, ni ARC te permitirá hacerlo.

Si ivar es un objeto derivado de NSObject, puede usar el valor de retorno directamente o escribirlo para convertirlo en el objeto que espera sin problemas, con ARC o sin ARC.

Las respuestas son un poco antiguas.Con ARC y estructuras (o para estar seguro al acceder a cualquier iVar que no sea un objeto), debería hacerlo así:

ptrdiff_t offset = ivar_getOffset(ivar);
unsigned char *stuffBytes = (unsigned char *)(__bridge void *)object;
CGRect gilligans = * ((CGRect *)(stuffBytes + offset));

Al menos, esta era la única forma de que me funcionara.

Tomado de esta página: http://www.bignerdranch.com/blog/inside-the-bracket-part-5-runtime-api/

Sé que es un poco tarde para comentar :) Pero me enfrenté al mismo problema y todos los enfoques tenían problemas diferentes.ivar_getOffset no pasa el desinfectante de direcciones al menos.Pero todo funciona con KVC.Entonces, en lugar de usar los punteros, simplemente use [object setValue: value forKey: key], donde value es su valor envuelto (use @ (value) para valores simples / fundamentales) y key es el nombre de su ivar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top