123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #import <objc/runtime.h>
- #import "JastorRuntimeHelper.h"
- #import "Jastor.h"
- static const char *property_getTypeName(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') {
- size_t len = strlen(attribute);
- attribute[len - 1] = '\0';
- return (const char *)[[NSData dataWithBytes:(attribute + 3) length:len - 2] bytes];
- }
- }
- return "@";
- }
- @implementation JastorRuntimeHelper
- static NSMutableDictionary *propertyListByClass;
- static NSMutableDictionary *propertyClassByClassAndPropertyName;
- + (BOOL)isPropertyReadOnly:(Class)klass propertyName:(NSString*)propertyName{
- const char * type = property_getAttributes(class_getProperty(klass, [propertyName UTF8String]));
- NSString * typeString = [NSString stringWithUTF8String:type];
- NSArray * attributes = [typeString componentsSeparatedByString:@","];
- NSString * typeAttribute = [attributes objectAtIndex:1];
- return [typeAttribute rangeOfString:@"R"].length > 0;
- }
- + (NSArray *)propertyNames:(Class)klass {
- if (klass == [Jastor class]) {
- return [NSArray array];
- }
- if (!propertyListByClass) {
- propertyListByClass = [[NSMutableDictionary alloc] init];
- }
-
- NSString *className = NSStringFromClass(klass);
- NSArray *value = [propertyListByClass objectForKey:className];
-
- if (value) {
- return value;
- }
-
- NSMutableArray *propertyNamesArray = [NSMutableArray array];
- unsigned int propertyCount = 0;
- objc_property_t *properties = class_copyPropertyList(klass, &propertyCount);
-
- for (unsigned int i = 0; i < propertyCount; ++i) {
- objc_property_t property = properties[i];
- const char * name = property_getName(property);
-
- [propertyNamesArray addObject:[NSString stringWithUTF8String:name]];
- }
- free(properties);
-
- [propertyListByClass setObject:propertyNamesArray forKey:className];
- NSArray* arr = [JastorRuntimeHelper propertyNames:class_getSuperclass(klass)];
- [propertyNamesArray addObjectsFromArray:arr];
- return propertyNamesArray;
- }
- + (Class)propertyClassForPropertyName:(NSString *)propertyName ofClass:(Class)klass {
- if (!propertyClassByClassAndPropertyName) {
- propertyClassByClassAndPropertyName = [[NSMutableDictionary alloc] init];
- }
-
- NSString *key = [NSString stringWithFormat:@"%@:%@", NSStringFromClass(klass), propertyName];
- NSString *value = [propertyClassByClassAndPropertyName objectForKey:key];
-
- if (value) {
- return NSClassFromString(value);
- }
-
- unsigned int propertyCount = 0;
- objc_property_t *properties = class_copyPropertyList(klass, &propertyCount);
-
- const char * cPropertyName = [propertyName UTF8String];
-
- for (unsigned int i = 0; i < propertyCount; ++i) {
- objc_property_t property = properties[i];
- const char * name = property_getName(property);
- if (strcmp(cPropertyName, name) == 0) {
- free(properties);
- NSString *className = [NSString stringWithUTF8String:property_getTypeName(property)];
- [propertyClassByClassAndPropertyName setObject:className forKey:key];
- //we found the property - we need to free
- return NSClassFromString(className);
- }
- }
- free(properties);
- //this will support traversing the inheritance chain
- return [self propertyClassForPropertyName:propertyName ofClass:class_getSuperclass(klass)];
- }
- @end
|