Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective- C - Looping through all properties in a class?

Is there a way to loop through all properties in an object and get their "name" and "value".

I am trying to write a category to serialize objects to a string, based on their property name and values. I'm trying to prevent writing encoding methods for each class, and instead write a generic one.

Is this possible?

like image 310
aryaxt Avatar asked Feb 12 '12 19:02

aryaxt


3 Answers

You can use this code to enumerate all properties declared in a class, and all attributes of the properties. I guess you're more interested in parsing the type attribute. They are detailed here.

unsigned int numOfProperties;
objc_property_t *properties = class_copyPropertyList([self class], &numOfProperties);
for ( unsigned int pi = 0; pi < numOfProperties; pi++ ) {
    // Examine the property attributes
    unsigned int numOfAttributes;
    objc_property_attribute_t *propertyAttributes = property_copyAttributeList(properties[pi], &numOfAttributes);
    for ( unsigned int ai = 0; ai < numOfAttributes; ai++ ) {
        switch (propertyAttributes[ai].name[0]) {
            case 'T': // type
                break;
            case 'R': // readonly
                break;
            case 'C': // copy 
                break;
            case '&': // retain
                break;
            case 'N': // nonatomic 
                break;
            case 'G': // custom getter
                break;
            case 'S': // custom setter
                break;
            case 'D': // dynamic 
                break;
            default: 
                break;
        }
    }
    free(propertyAttributes);
}
free(properties);
like image 173
Costique Avatar answered Nov 12 '22 05:11

Costique


I use the following Category on NSObject to say, for example, NSLog(@"%@", [someObject propertiesPlease]);, resulting in a log entry like…

someObject: {
    color = "NSCalibratedRGBColorSpace 0 0 1 1";
    crayon = Blueberry;
}

NSObject+Additions.h

@interface NSObject (Additions)
- (NSDictionary *)propertiesPlease;
@end

NSObject+Additions.m

@implementation NSObject (Additions)
- (NSDictionary *)propertiesPlease {
NSMutableDictionary *props = [NSMutableDictionary dictionary];
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];
   NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property)];
   id propertyValue = [self valueForKey:(NSString *)propertyName];
   if (propertyValue) [props setObject:propertyValue forKey:propertyName];
}
   free(properties);
   return props;
}
@end
like image 39
Alex Gray Avatar answered Nov 12 '22 07:11

Alex Gray


Maybe class_copyPropertyList() will do what you are after - but notice that it only returns declared properties.

Not all properties are declared - NSDictionary and NSMutableDictionary are examples of classes where you can set properties that are not declared in the class.

More in the docs.

like image 1
Monolo Avatar answered Nov 12 '22 05:11

Monolo