5

Ok, so say I have a property on a class:

@interface MyObject : NSObject {
    MyOtherObject *someOtherObject;
}

@property (nonatomic, copy) MyOtherObject *someOtherObject;

@end

I'm trying to create something to deserialize an API response into the correct objects without explicitly defining what class each api attribute maps to. So, is there any way for me to find out what class a property is, even if it's nil? What I'm looking for is some method like [MyObject classForProperty:@"someOtherObject"] which would return a Class object. Note--I'm not looking for isKindOfClass: or just class, as those won't work on a nil value.

Worst case, I can just manually define a list of property classes, but it'd be really nice if there were some built in way to do it.

Kyle Slattery
  • 33,318
  • 9
  • 32
  • 36

1 Answers1

2

Ok, I ended up figuring this out after coming across this question: In Objective-C Determine if a Property is an int, float, double, NSString, NSDate, NSNumber, etc

Here's the code:

@interface NSObject (Properties)

+ (Class)classForProperty:(NSString *)propertyName;

@end

#import <objc/runtime.h>

@implementation NSObject (Properties)

+ (Class)classForProperty:(NSString *)propertyName {
    const char *attributes = property_getAttributes(class_getProperty([self class], [propertyName UTF8String]));
    NSString *attributesString = [NSString stringWithUTF8String:attributes];
    NSArray *parts = [attributesString componentsSeparatedByString:@","];
    NSString *typeString = [[parts objectAtIndex:0] substringFromIndex:1];

    if ([typeString hasPrefix:@"@"] && [typeString length] > 1) {
        NSString *name = [typeString substringWithRange:NSMakeRange(2, [typeString length]-3)];
        Class theClass = NSClassFromString(name);
        return theClass;
    }

    return nil;
}

@end

It seems to work pretty well for me, but any modifications are definitely welcome.

Community
  • 1
  • 1
Kyle Slattery
  • 33,318
  • 9
  • 32
  • 36
  • 1
    Ewww... you really don't want to do that. The `@property` type encoding string is horribly fragile, likely to change in future compilers, and -- in general -- this kind of a coding pattern is discouraged. Far better to create a model description layer of your own (or use Core Data). – bbum May 11 '11 at 15:15
  • Why not just use Key-Value Coding to deserialize? – more tension May 11 '11 at 16:00
  • bbum--good to know, maybe I'll just end up manually making the model description – Kyle Slattery May 11 '11 at 20:00
  • more tension--Unless I'm missing something, you still can't determine the class of a property, right? – Kyle Slattery May 11 '11 at 20:01