2009-10-27 19 views

Respuesta

8

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]; 
} 
+2

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í. –

+0

totalmente a la derecha. Gracias. – nall

+0

Se imprime solo Bar :: s1. ¿Pero dónde i1? –

6

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.

4

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); 
Cuestiones relacionadas