Created
August 3, 2010 03:01
-
-
Save lilyball/505755 to your computer and use it in GitHub Desktop.
Method to iterate the properties on an object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* objc+blocks.h | |
* | |
* Created by Kevin Ballard on 1/13/10. | |
* | |
*/ | |
#import <objc/runtime.h> | |
enum { | |
PropertyIteratorFlagReadonly = (1 << 0), | |
PropertyIteratorFlagCopy = (1 << 1), | |
PropertyIteratorFlagRetain = (1 << 2), | |
PropertyIteratorFlagNonatomic = (1 << 3), | |
PropertyIteratorFlagDynamic = (1 << 4), | |
PropertyIteratorFlagWeak = (1 << 5), | |
PropertyIteratorFlagCollectable = (1 << 6), | |
}; | |
typedef NSUInteger PropertyIteratorFlags; | |
typedef struct PropertyIteratorInfo { | |
NSString *name; | |
PropertyIteratorFlags flags; | |
NSString *typeEncoding; | |
SEL getter; | |
SEL setter; | |
NSString *ivar; | |
} PropertyIteratorInfo; | |
void objc_iterateProperties(id obj, void (^iterator)(PropertyIteratorInfo info)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* objc+blocks.m | |
* | |
* Created by Kevin Ballard on 1/13/10. | |
* | |
*/ | |
#include "objc+blocks.h" | |
void objc_iterateProperties(id obj, void (^iterator)(PropertyIteratorInfo info)) { | |
for (Class klass = [obj class]; klass != [NSObject class]; klass = [klass superclass]) { | |
unsigned int pCount; | |
objc_property_t *props = class_copyPropertyList(klass, &pCount); | |
for (unsigned int i = 0; i < pCount; i++) { | |
NSString *attrs = [NSString stringWithUTF8String:property_getAttributes(props[i])]; | |
NSArray *comps = [attrs componentsSeparatedByString:@","]; | |
PropertyIteratorInfo info = {0}; | |
info.name = [NSString stringWithUTF8String:property_getName(props[i])]; | |
for (NSString *comp in comps) { | |
unichar c = [comp characterAtIndex:0]; | |
comp = [comp substringFromIndex:1]; | |
switch (c) { | |
case 'T': // property type | |
info.typeEncoding = comp; | |
break; | |
case 'R': // readonly | |
info.flags |= PropertyIteratorFlagReadonly; | |
break; | |
case 'C': // copy | |
info.flags |= PropertyIteratorFlagCopy; | |
break; | |
case '&': // retain | |
info.flags |= PropertyIteratorFlagRetain; | |
break; | |
case 'N': // nonatomic | |
info.flags |= PropertyIteratorFlagNonatomic; | |
break; | |
case 'G': // getter | |
info.getter = NSSelectorFromString(comp); | |
break; | |
case 'S': // setter | |
info.setter = NSSelectorFromString(comp); | |
break; | |
case 'D': // dynamic | |
info.flags |= PropertyIteratorFlagDynamic; | |
break; | |
case 'W': // weak | |
info.flags |= PropertyIteratorFlagWeak; | |
break; | |
case 'P': // eligible for garbage collection | |
info.flags |= PropertyIteratorFlagCollectable; | |
break; | |
case 't': // old-style type encoding; ignore this | |
break; | |
case 'V': // backing ivar name | |
info.ivar = comp; | |
break; | |
} | |
} | |
if (info.setter == NULL && !(info.flags & PropertyIteratorFlagReadonly)) { | |
info.setter = NSSelectorFromString([@"set" stringByAppendingString:[info.name capitalizedString]]); | |
} | |
if (info.getter == NULL) { | |
info.getter = NSSelectorFromString(info.name); | |
} | |
iterator(info); | |
} | |
free(props); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment