poligono para pairs librerias graficos graficas graficar grafica funcion ejemplos animados objective-c class properties attributes introspection

objective-c - para - poligono en r



Obtener una lista de propiedades de objeto en Objective-C (13)

Cuando probé con iOS 3.2, la función getPropertyType no funciona bien con la descripción de la propiedad. Encontré un ejemplo de la documentación de iOS: "Guía de programación de tiempo de ejecución de Objective-C: Propiedades declaradas".

Aquí hay un código revisado para la lista de propiedades en iOS 3.2:

#import <objc/runtime.h> #import <Foundation/Foundation.h> ... unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList([UITouch class], &outCount); for(i = 0; i < outCount; i++) { objc_property_t property = properties[i]; fprintf(stdout, "%s %s/n", property_getName(property), property_getAttributes(property)); } free(properties);

¿Cómo puedo obtener una lista (en forma de NSArray o NSDictionary ) de los atributos de un objeto dado en Objective-C?

Imagine el siguiente escenario: he definido una clase principal que solo amplía NSObject , que contiene un NSString , un BOOL y un objeto NSData como atributos. Luego tengo varias clases que extienden esta clase principal, agregando muchos atributos diferentes cada uno.

¿Hay alguna manera de que pueda implementar un método de instancia en la clase principal que atraviesa todo el objeto y devuelve, por ejemplo, un NSArray de cada uno de los atributos de clase (secundarios) como NSStrings que no están en la clase principal, para que pueda hacerlo más tarde? usar estos NSString para KVC?


Descubrí que la solución de boliva funciona bien en el simulador, pero en el dispositivo la subcadena de longitud fija causa problemas. He escrito una solución más amigable para Objective-C para este problema que funciona en el dispositivo. En mi versión, convierto el C-String de los atributos a un NSString y realizo operaciones de cadena sobre él para obtener una subcadena de la descripción del tipo.

/* * @returns A string describing the type of the property */ + (NSString *)propertyTypeStringOfProperty:(objc_property_t) property { const char *attr = property_getAttributes(property); NSString *const attributes = [NSString stringWithCString:attr encoding:NSUTF8StringEncoding]; NSRange const typeRangeStart = [attributes rangeOfString:@"T@/""]; // start of type string if (typeRangeStart.location != NSNotFound) { NSString *const typeStringWithQuote = [attributes substringFromIndex:typeRangeStart.location + typeRangeStart.length]; NSRange const typeRangeEnd = [typeStringWithQuote rangeOfString:@"/""]; // end of type string if (typeRangeEnd.location != NSNotFound) { NSString *const typeString = [typeStringWithQuote substringToIndex:typeRangeEnd.location]; return typeString; } } return nil; } /** * @returns (NSString) Dictionary of property name --> type */ + (NSDictionary *)propertyTypeDictionaryOfClass:(Class)klass { NSMutableDictionary *propertyMap = [NSMutableDictionary dictionary]; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(klass, &outCount); for(i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if(propName) { NSString *propertyName = [NSString stringWithCString:propName encoding:NSUTF8StringEncoding]; NSString *propertyType = [self propertyTypeStringOfProperty:property]; [propertyMap setValue:propertyType forKey:propertyName]; } } free(properties); return propertyMap; }


Esta implementación funciona con los tipos de objeto Objective-C y las primitivas C. Es iOS 8 compatible. Esta clase proporciona tres métodos de clase:

+ (NSDictionary *) propertiesOfObject:(id)object;

Devuelve un diccionario de todas las propiedades visibles de un objeto, incluidas las de todas sus superclases.

+ (NSDictionary *) propertiesOfClass:(Class)class;

Devuelve un diccionario de todas las propiedades visibles de una clase, incluidas las de todas sus superclases.

+ (NSDictionary *) propertiesOfSubclass:(Class)class;

Devuelve un diccionario de todas las propiedades visibles que son específicas de una subclase. Las propiedades para sus superclases no están incluidas.

Un ejemplo útil del uso de estos métodos es copiar un objeto a una instancia de subclase en Objective-C sin tener que especificar las propiedades en un método de copia . Las partes de esta respuesta se basan en las otras respuestas a esta pregunta pero proporcionan una interfaz más limpia para la funcionalidad deseada.

Encabezamiento:

// SYNUtilities.h #import <Foundation/Foundation.h> @interface SYNUtilities : NSObject + (NSDictionary *) propertiesOfObject:(id)object; + (NSDictionary *) propertiesOfClass:(Class)class; + (NSDictionary *) propertiesOfSubclass:(Class)class; @end

Implementación:

// SYNUtilities.m #import "SYNUtilities.h" #import <objc/objc-runtime.h> @implementation SYNUtilities + (NSDictionary *) propertiesOfObject:(id)object { Class class = [object class]; return [self propertiesOfClass:class]; } + (NSDictionary *) propertiesOfClass:(Class)class { NSMutableDictionary * properties = [NSMutableDictionary dictionary]; [self propertiesForHierarchyOfClass:class onDictionary:properties]; return [NSDictionary dictionaryWithDictionary:properties]; } + (NSDictionary *) propertiesOfSubclass:(Class)class { if (class == NULL) { return nil; } NSMutableDictionary *properties = [NSMutableDictionary dictionary]; return [self propertiesForSubclass:class onDictionary:properties]; } + (NSMutableDictionary *)propertiesForHierarchyOfClass:(Class)class onDictionary:(NSMutableDictionary *)properties { if (class == NULL) { return nil; } if (class == [NSObject class]) { // On reaching the NSObject base class, return all properties collected. return properties; } // Collect properties from the current class. [self propertiesForSubclass:class onDictionary:properties]; // Collect properties from the superclass. return [self propertiesForHierarchyOfClass:[class superclass] onDictionary:properties]; } + (NSMutableDictionary *) propertiesForSubclass:(Class)class onDictionary:(NSMutableDictionary *)properties { unsigned int outCount, i; objc_property_t *objcProperties = class_copyPropertyList(class, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = objcProperties[i]; const char *propName = property_getName(property); if(propName) { const char *propType = getPropertyType(property); NSString *propertyName = [NSString stringWithUTF8String:propName]; NSString *propertyType = [NSString stringWithUTF8String:propType]; [properties setObject:propertyType forKey:propertyName]; } } free(objcProperties); return properties; } static const char *getPropertyType(objc_property_t property) { const char *attributes = property_getAttributes(property); char buffer[1 + strlen(attributes)]; strcpy(buffer, attributes); char *state = buffer, *attribute; while ((attribute = strsep(&state, ",")) != NULL) { if (attribute[0] == ''T'' && attribute[1] != ''@'') { // A C primitive type: /* For example, int "i", long "l", unsigned "I", struct. Apple docs list plenty of examples of values returned. For a list of what will be returned for these primitives, search online for "Objective-c" "Property Attribute Description Examples" */ NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding]; return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding]; } else if (attribute[0] == ''T'' && attribute[1] == ''@'' && strlen(attribute) == 2) { // An Objective C id type: return "id"; } else if (attribute[0] == ''T'' && attribute[1] == ''@'') { // Another Objective C id type: NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding]; return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding]; } } return ""; } @end


Estaba usando la función boliva provista, pero aparentemente dejó de funcionar con iOS 7. Así que ahora, en lugar de static const char * getPropertyType (propiedad objc_property_t) uno puede usar lo siguiente:

- (NSString*) classOfProperty:(NSString*)propName{ objc_property_t prop = class_getProperty([self class], [propName UTF8String]); if (!prop) { // doesn''t exist for object return nil; } const char * propAttr = property_getAttributes(prop); NSString *propString = [NSString stringWithUTF8String:propAttr]; NSArray *attrArray = [propString componentsSeparatedByString:@","]; NSString *class=[attrArray objectAtIndex:0]; return [[class stringByReplacingOccurrencesOfString:@"/"" withString:@""] stringByReplacingOccurrencesOfString:@"T@" withString:@""]; }


Estas respuestas son útiles, pero necesito más de eso. Todo lo que quiero hacer es verificar si el tipo de clase de una propiedad es igual a la de un objeto existente. Todos los códigos anteriores no son capaces de hacerlo, porque: Para obtener el nombre de clase de un objeto, object_getClassName () devuelve textos como estos:

__NSArrayI (for an NSArray instance) __NSArrayM (for an NSMutableArray instance) __NSCFBoolean (an NSNumber object initialized by initWithBool:) __NSCFNumber (an NSValue object initialized by [NSNumber initWithBool:])

Pero si invoca getPropertyType (...) desde el código de ejemplo anterior, con 4 objc_property_t estructuras de propiedades de una clase definida así:

@property (nonatomic, strong) NSArray* a0; @property (nonatomic, strong) NSArray* a1; @property (nonatomic, copy) NSNumber* n0; @property (nonatomic, copy) NSValue* n1;

devuelve cadenas respectivamente de la siguiente manera:

NSArray NSArray NSNumber NSValue

Por lo tanto, no puede determinar si un NSObject puede ser el valor de una propiedad de la clase. ¿Cómo hacer eso entonces?

Aquí está mi código de muestra completo (la función getPropertyType (...) es la misma que la anterior):

#import <objc/runtime.h> @interface FOO : NSObject @property (nonatomic, strong) NSArray* a0; @property (nonatomic, strong) NSArray* a1; @property (nonatomic, copy) NSNumber* n0; @property (nonatomic, copy) NSValue* n1; @end @implementation FOO @synthesize a0; @synthesize a1; @synthesize n0; @synthesize n1; @end static const char *getPropertyType(objc_property_t property) { const char *attributes = property_getAttributes(property); //printf("attributes=%s/n", attributes); char buffer[1 + strlen(attributes)]; strcpy(buffer, attributes); char *state = buffer, *attribute; while ((attribute = strsep(&state, ",")) != NULL) { if (attribute[0] == ''T'' && attribute[1] != ''@'') { // it''s a C primitive type: // if you want a list of what will be returned for these primitives, search online for // "objective-c" "Property Attribute Description Examples" // apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc. NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding]; return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding]; } else if (attribute[0] == ''T'' && attribute[1] == ''@'' && strlen(attribute) == 2) { // it''s an ObjC id type: return "id"; } else if (attribute[0] == ''T'' && attribute[1] == ''@'') { // it''s another ObjC object type: NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding]; return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding]; } } return ""; } int main(int argc, char * argv[]) { NSArray* a0 = [[NSArray alloc] init]; NSMutableArray* a1 = [[NSMutableArray alloc] init]; NSNumber* n0 = [[NSNumber alloc] initWithBool:YES]; NSValue* n1 = [[NSNumber alloc] initWithBool:NO]; const char* type0 = object_getClassName(a0); const char* type1 = object_getClassName(a1); const char* type2 = object_getClassName(n0); const char* type3 = object_getClassName(n1); objc_property_t property0 = class_getProperty(FOO.class, "a0"); objc_property_t property1 = class_getProperty(FOO.class, "a1"); objc_property_t property2 = class_getProperty(FOO.class, "n0"); objc_property_t property3 = class_getProperty(FOO.class, "n1"); const char * memberthype0 = getPropertyType(property0);//property_getAttributes(property0); const char * memberthype1 = getPropertyType(property1);//property_getAttributes(property1); const char * memberthype2 = getPropertyType(property2);//property_getAttributes(property0); const char * memberthype3 = getPropertyType(property3);//property_getAttributes(property1); NSLog(@"%s", type0); NSLog(@"%s", type1); NSLog(@"%s", type2); NSLog(@"%s", type3); NSLog(@"%s", memberthype0); NSLog(@"%s", memberthype1); NSLog(@"%s", memberthype2); NSLog(@"%s", memberthype3); return 0; }


La palabra "atributos" es un poco borrosa. ¿Quiere decir variables de instancia, propiedades, métodos que parecen accesos?

La respuesta a los tres es "sí, pero no es muy fácil". Objective-C runtime API incluye funciones para obtener la lista ivar, lista de métodos o lista de propiedades para una clase (por ejemplo, class_copyPropertyList() ) y luego una función correspondiente para cada tipo para obtener el nombre de un elemento en la lista (por ejemplo , property_getName() ).

Con todo, puede ser mucho trabajo hacer las cosas bien, o al menos mucho más de lo que la mayoría de la gente querría hacer por lo que normalmente es una característica realmente trivial.

Alternativamente, podría simplemente escribir un script de Ruby / Python que simplemente lea un archivo de encabezado y busque lo que considere "atributos" para la clase.


La respuesta de @ boliva es buena, pero necesita un poco más para manejar primitivas, como int, long, float, double, etc.

Construí de él para agregar esta funcionalidad.

// PropertyUtil.h #import @interface PropertyUtil : NSObject + (NSDictionary *)classPropsFor:(Class)klass; @end // PropertyUtil.m #import "PropertyUtil.h" #import "objc/runtime.h" @implementation PropertyUtil static const char * getPropertyType(objc_property_t property) { const char *attributes = property_getAttributes(property); printf("attributes=%s/n", attributes); char buffer[1 + strlen(attributes)]; strcpy(buffer, attributes); char *state = buffer, *attribute; while ((attribute = strsep(&state, ",")) != NULL) { if (attribute[0] == ''T'' && attribute[1] != ''@'') { // it''s a C primitive type: /* if you want a list of what will be returned for these primitives, search online for "objective-c" "Property Attribute Description Examples" apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc. */ return (const char *)[[NSData dataWithBytes:(attribute + 1) length:strlen(attribute) - 1] bytes]; } else if (attribute[0] == ''T'' && attribute[1] == ''@'' && strlen(attribute) == 2) { // it''s an ObjC id type: return "id"; } else if (attribute[0] == ''T'' && attribute[1] == ''@'') { // it''s another ObjC object type: return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes]; } } return ""; } + (NSDictionary *)classPropsFor:(Class)klass { if (klass == NULL) { return nil; } NSMutableDictionary *results = [[[NSMutableDictionary alloc] init] autorelease]; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(klass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if(propName) { const char *propType = getPropertyType(property); NSString *propertyName = [NSString stringWithUTF8String:propName]; NSString *propertyType = [NSString stringWithUTF8String:propType]; [results setObject:propertyType forKey:propertyName]; } } free(properties); // returning a copy here to make sure the dictionary is immutable return [NSDictionary dictionaryWithDictionary:results]; } @end


La respuesta de @ orange80 tiene un problema: en realidad no siempre termina la cadena con 0s. Esto puede llevar a resultados inesperados, como la falla al intentar convertirlo a UTF8 (de hecho, tuve un crashbug bastante molesto por eso. Fue divertido depurarlo ^^). Lo arreglé obteniendo realmente un NSString del atributo y luego llamando a cStringUsingEncoding :. Esto funciona como un encanto ahora. (También funciona con ARC, al menos para mí)

Así que esta es mi versión del código ahora:

// PropertyUtil.h #import @interface PropertyUtil : NSObject + (NSDictionary *)classPropsFor:(Class)klass; @end // PropertyUtil.m #import "PropertyUtil.h" #import <objc/runtime.h> @implementation PropertyUtil static const char *getPropertyType(objc_property_t property) { const char *attributes = property_getAttributes(property); //printf("attributes=%s/n", attributes); char buffer[1 + strlen(attributes)]; strcpy(buffer, attributes); char *state = buffer, *attribute; while ((attribute = strsep(&state, ",")) != NULL) { if (attribute[0] == ''T'' && attribute[1] != ''@'') { // it''s a C primitive type: /* if you want a list of what will be returned for these primitives, search online for "objective-c" "Property Attribute Description Examples" apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc. */ NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding]; return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding]; } else if (attribute[0] == ''T'' && attribute[1] == ''@'' && strlen(attribute) == 2) { // it''s an ObjC id type: return "id"; } else if (attribute[0] == ''T'' && attribute[1] == ''@'') { // it''s another ObjC object type: NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding]; return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding]; } } return ""; } + (NSDictionary *)classPropsFor:(Class)klass { if (klass == NULL) { return nil; } NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(klass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if(propName) { const char *propType = getPropertyType(property); NSString *propertyName = [NSString stringWithUTF8String:propName]; NSString *propertyType = [NSString stringWithUTF8String:propType]; [results setObject:propertyType forKey:propertyName]; } } free(properties); // returning a copy here to make sure the dictionary is immutable return [NSDictionary dictionaryWithDictionary:results]; } @end


Para los espectadores de Swift, puede obtener esta funcionalidad utilizando la funcionalidad Encodable . Explicaré cómo:

  1. Conforme su objeto al protocolo Encodable

    class ExampleObj: NSObject, Encodable { var prop1: String = "" var prop2: String = "" }

  2. Crear una extensión para Encodable para proporcionar funcionalidad toDictionary

    public func toDictionary() -> [String: AnyObject]? { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted guard let data = try? encoder.encode(self), let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let jsonDict = json as? [String: AnyObject] else { return nil } return jsonDict }

  3. Llame a toDictionary en su instancia de objeto y acceda a la propiedad de keys .

    let exampleObj = ExampleObj() exampleObj.toDictionary()?.keys

  4. Voila! Acceda a sus propiedades de la siguiente manera:

    for k in exampleObj!.keys { print(k) } // Prints "prop1" // Prints "prop2"


Pude obtener la respuesta de @ orange80 para trabajar CON ARC HABILITADO ... ... por lo que quería, al menos ... pero no sin un poco de prueba y error. Con suerte, esta información adicional puede ahorrarle a alguien el dolor.

Guarde las clases que describe en su answer = como clase, y en su AppDelegate.h (o lo que sea), ponga #import PropertyUtil.h . Entonces en tu ...

- (void)applicationDidFinishLaunching: (NSNotification *)aNotification {

método (o lo que sea)

PropertyUtil *props = [PropertyUtil new]; NSDictionary *propsD = [PropertyUtil classPropsFor: (NSObject*)[gist class]]; NSLog(@"%@, %@", props, propsD); …

El secreto es emitir la variable de instancia de tu clase ( en este caso mi clase es Gist , y mi instancia de Gist es gist ) que quieres consultar ... a NSObject ... (id) , etc., no lo cortará .. por varias razones extrañas y esotéricas. Esto te dará un resultado como ese ...

<PropertyUtil: 0x7ff0ea92fd90>, { apiURL = NSURL; createdAt = NSDate; files = NSArray; gistDescription = NSString; gistId = NSString; gitPullURL = NSURL; gitPushURL = NSURL; htmlURL = NSURL; isFork = c; isPublic = c; numberOfComments = Q; updatedAt = NSDate; userLogin = NSString; }

Para toda la jactancia de OCD sin vergüenza de Apple sobre la "introspección" de ObjC "Amazeballs" ... Seguro que no hacen que sea muy fácil realizar esta simple "mirada" "a uno mismo", "por así decirlo" ...

Si realmente quieres volverte loco ... mira ... class-dump , que es una manera alucinante de echar un vistazo a los encabezados de clase de CUALQUIER ejecutable, etc ... Proporciona una mirada VERBOSA en tus clases ... que yo, personalmente, encuentre verdaderamente útil, en muchas, muchas circunstancias. en realidad es por eso que comencé a buscar una solución a la pregunta del OP. aquí están algunos de los parámetros de uso ... ¡disfruta!

-a show instance variable offsets -A show implementation addresses --arch <arch> choose a specific architecture from a universal binary (ppc, ppc64, i386, x86_64) -C <regex> only display classes matching regular expression -f <str> find string in method name -I sort classes, categories, and protocols by inheritance (overrides -s) -r recursively expand frameworks and fixed VM shared libraries -s sort classes and categories by name -S sort methods by name


Si alguien está en la necesidad de obtener también las propiedades heredadas de las clases principales (como yo lo hice) aquí hay alguna modificación en el código " orange80 " para que sea recursivo:

+ (NSDictionary *)classPropsForClassHierarchy:(Class)klass onDictionary:(NSMutableDictionary *)results { if (klass == NULL) { return nil; } //stop if we reach the NSObject class as is the base class if (klass == [NSObject class]) { return [NSDictionary dictionaryWithDictionary:results]; } else{ unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(klass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if(propName) { const char *propType = getPropertyType(property); NSString *propertyName = [NSString stringWithUTF8String:propName]; NSString *propertyType = [NSString stringWithUTF8String:propType]; [results setObject:propertyType forKey:propertyName]; } } free(properties); //go for the superclass return [PropertyUtil classPropsForClassHierarchy:[klass superclass] onDictionary:results]; } }


Solo pude obtener la respuesta yo mismo. Al utilizar Obj-C Runtime Library, tuve acceso a las propiedades de la manera que quería:

- (void)myMethod { unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList([self class], &outCount); for(i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if(propName) { const char *propType = getPropertyType(property); NSString *propertyName = [NSString stringWithCString:propName encoding:[NSString defaultCStringEncoding]]; NSString *propertyType = [NSString stringWithCString:propType encoding:[NSString defaultCStringEncoding]]; ... } } free(properties); }

Esto me requirió hacer una función C ''getPropertyType'', que se toma principalmente de una muestra de código de Apple (no recuerdo en este momento la fuente exacta):

static const char *getPropertyType(objc_property_t property) { const char *attributes = property_getAttributes(property); char buffer[1 + strlen(attributes)]; strcpy(buffer, attributes); char *state = buffer, *attribute; while ((attribute = strsep(&state, ",")) != NULL) { if (attribute[0] == ''T'') { if (strlen(attribute) <= 4) { break; } return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes]; } } return "@"; }


Tienes tres hechizos mágicos

Ivar* ivars = class_copyIvarList(clazz, &count); // to get all iVars objc_property_t *properties = class_copyPropertyList(clazz, &count); //to get all properties of a class Method* methods = class_copyMethodList(clazz, &count); // to get all methods of a class.

El siguiente código puede ayudarte.

-(void) displayClassInfo { Class clazz = [self class]; u_int count; Ivar* ivars = class_copyIvarList(clazz, &count); NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count ; i++) { const char* ivarName = ivar_getName(ivars[i]); ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]]; } free(ivars); objc_property_t* properties = class_copyPropertyList(clazz, &count); NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count ; i++) { const char* propertyName = property_getName(properties[i]); [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]]; } free(properties); Method* methods = class_copyMethodList(clazz, &count); NSMutableArray* methodArray = [NSMutableArray arrayWithCapacity:count]; for (int i = 0; i < count ; i++) { SEL selector = method_getName(methods[i]); const char* methodName = sel_getName(selector); [methodArray addObject:[NSString stringWithCString:methodName encoding:NSUTF8StringEncoding]]; } free(methods); NSDictionary* classInfo = [NSDictionary dictionaryWithObjectsAndKeys: ivarArray, @"ivars", propertyArray, @"properties", methodArray, @"methods", nil]; NSLog(@"%@", classInfo); }