¿Hay alguna forma de obtener algo así como un diccionario de todos los pares clave-valor de una clase?¿Hay alguna manera de determinar dinámicamente los ivars de una clase en tiempo de ejecución en Cocoa/Cocoa Touch?
Respuesta
Tendría que hacer su propio uso del Objective-C Runtime functions. Aquí hay un código de muestra muy básico. Tenga en cuenta que obtener los ivars de una clase no obtiene los ivars de su superclase. Tendría que hacer eso explícitamente, pero las funciones están todas allí en el tiempo de ejecución.
#import <objc/objc-runtime.h>
#include <inttypes.h>
#include <Foundation/Foundation.h>
@interface Foo : NSObject
{
int i1;
}
@end
@implementation Foo
@end
@interface Bar : Foo
{
NSString* s1;
}
@end
@implementation Bar
@end
int main(int argc, char** argv)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
unsigned int count;
Ivar* ivars = class_copyIvarList([Bar class], &count);
for(unsigned int i = 0; i < count; ++i)
{
NSLog(@"%@::%s", [Bar class], ivar_getName(ivars[i]));
}
free(ivars);
[pool release];
}
No estoy seguro de por sólo Ivars, pero si los tiene definidos como propiedades es posible acceder a las propiedades disponibles en una clase.
He estado usando SQLitePersistentObjects para un par de proyectos y tiene algún código útil que obtiene las propiedades definidas en la clase para usar al calcular la serialización hacia y desde sqlite.
Utiliza la función class_copyPropertyList para obtener la lista de propiedades disponibles en una clase.
Más específicamente:
+(NSDictionary *)propertiesWithEncodedTypes
{
// DO NOT use a static variable to cache this, it will cause problem with subclasses of classes that are subclasses of SQLitePersistentObject
// Recurse up the classes, but stop at NSObject. Each class only reports its own properties, not those inherited from its superclass
NSMutableDictionary *theProps;
if ([self superclass] != [NSObject class])
theProps = (NSMutableDictionary *)[[self superclass] propertiesWithEncodedTypes];
else
theProps = [NSMutableDictionary dictionary];
unsigned int outCount;
objc_property_t *propList = class_copyPropertyList([self class], &outCount);
int i;
// Loop through properties and add declarations for the create
for (i=0; i < outCount; i++)
{
objc_property_t * oneProp = propList + i;
NSString *propName = [NSString stringWithUTF8String:property_getName(*oneProp)];
NSString *attrs = [NSString stringWithUTF8String: property_getAttributes(*oneProp)];
NSArray *attrParts = [attrs componentsSeparatedByString:@","];
if (attrParts != nil)
{
if ([attrParts count] > 0)
{
NSString *propType = [[attrParts objectAtIndex:0] substringFromIndex:1];
[theProps setObject:propType forKey:propName];
}
}
}
free(propList);
return theProps;
}
Esto devuelve un diccionario de las propiedades - que necesita para hacer un poco de investigación de los resultados que obtiene de vuelta, pero usted debería ser capaz de conseguir lo que necesitas si estás usando propiedades.
Sí, totalmente posible:
int numIvars = 0;
Ivar * ivars = class_copyIvarList([anInstanceOfAClass class], &numIvars);
NSMutableDictionary * pairs = [NSMutableDictionary dictionary];
for (int i = 0; i < numIvars; ++i) {
Ivar ivar = ivars[i];
NSString * ivarName = [NSString stringWithCString:ivar_getName(ivar) encoding:NSUTF8StringEncoding];
id ivarValue = [anInstanceOfAClass valueForKey:ivarName];
[pairs setObject:ivarValue forKey:ivarName];
}
free(ivars);
NSLog(@"%@", pairs);
- 1. ¿Hay alguna manera de obtener el bytecode para una clase en tiempo de ejecución?
- 2. ¿Hay alguna manera de cargar un archivo de clase para ensamblar en tiempo de ejecución?
- 3. ¿Hay alguna manera de "extender" una clase en SASS?
- 4. ¿Hay alguna manera de anular automáticamente ToString() en una clase?
- 5. ¿Hay alguna sobrecarga en tiempo de ejecución para leer solo?
- 6. Crear tablas dinámicamente en tiempo de ejecución
- 7. ¿Hay alguna manera de presentar dinámicamente una versión oculta de un campo django en una plantilla?
- 8. ¿Hay alguna manera en Eclipse para determinar qué está consumiendo tiempo de CPU?
- 9. ¿Hay alguna manera de acceder a Ribbon (XML) en tiempo de ejecución?
- 10. ¿Hay alguna manera de obtener la identificación del paquete en tiempo de ejecución?
- 11. ¿Hay alguna manera de detener el tiempo. ¿Duerme en Windows?
- 12. ¿Cómo creo una propiedad de clase estática de PHP en tiempo de ejecución (dinámicamente)?
- 13. Genera dinámicamente clases en tiempo de ejecución en php?
- 14. ¿Cómo crear dinámicamente métodos de instancia en tiempo de ejecución?
- 15. Ruby - dinámicamente añadir una propiedad a la clase (en tiempo de ejecución)
- 16. Java: Extendiendo clase en tiempo de ejecución
- 17. ¿Hay alguna manera de crear elementos dinámicamente <rich:tab>?
- 18. ¿Hay alguna manera de usar variables locales en los módulos?
- 19. ¿Hay alguna manera de cargar un archivo JS local dinámicamente?
- 20. ¿Hay alguna manera de detectar lectores abiertos en una SqlConnection?
- 21. ¿Hay alguna manera de determinar el tamaño físico del monitor?
- 22. ¿Hay una manera fácil de encontrar el entorno de tiempo de ejecución en Pyramid
- 23. Tiempo de ejecución moderno Objective-c utilizando propiedades y ivars en el bloque de interfaz
- 24. ¿Hay alguna manera de determinar la cantidad de RAM de video gratuita en Linux?
- 25. En Scala, ¿hay alguna manera fácil de convertir una clase de caso en una tupla?
- 26. Generación de ensamblado de DLL dinámicamente en tiempo de ejecución
- 27. ¿Hay alguna manera de probar multi-touch en el emulador de Android?
- 28. ¿Hay alguna manera de que PHP imprima los datos en un navegador web en tiempo real?
- 29. ¿Hay alguna manera de elegir dinámicamente una estrategia @GeneratedValue utilizando anotaciones JPA e Hibernate?
- 30. ¿Hay alguna manera de determinar las funciones no utilizadas en Xcode4?
Desde '' class_copyIvarList' ha copy' en el nombre, usted es responsable de la limpieza de la memoria. Por lo tanto, también necesita 'libre (ivars);' allí. –
totalmente a la derecha. Gracias. – nall
Se imprime solo Bar :: s1. ¿Pero dónde i1? –