Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

property type or class using reflection

I was wondering if it's possible to determine the class or primitive type of an Objects properties. Getting all properties names and values is pretty easy. SO answer

So is there any way to get the properties class type while the property hast no value or nil value?

Example Code

@interface MyObject : NSObject
@property (nonatomic, copy) NSString *aString;
@property (nonatomic, copy) NSDate *aDate;
@property                   NSInteger aPrimitive;
@end

@implementation MyObject
@synthesize aString;
@synthesize aDate;
@synthesize aPrimitive;

- (void)getTheTypesOfMyProperties {
    unsigned int count;
    objc_property_t* props = class_copyPropertyList([self class], &count);
    for (int i = 0; i < count; i++) {
        objc_property_t property = props[i];

        // Here I can easy get the name or value
        const char * name = property_getName(property);

        // But is there any magic function that can tell me the type?
        // the property can be nil at this time
        Class cls = magicFunction(property);
    }
    free(props);
}

@end
like image 434
Arndt Bieberstein Avatar asked May 31 '13 15:05

Arndt Bieberstein


People also ask

How do I find property type?

To determine the type of a particular property, do the following: Get a Type object that represents the type (the class or structure) that contains the property. If you are working with an object (an instance of a type), you can call its GetType method.

What is reflection of type?

Reflection is divided into three types: diffuse, specular, and glossy.

How does reflection set property value?

To set property values via Reflection, you must use the Type. GetProperty() method, then invoke the PropertyInfo. SetValue() method. The default overload that we used accepts the object in which to set the property value, the value itself, and an object array, which in our example is null.

Is it good to use reflection in C#?

Reflection in C# is used to retrieve metadata on types at runtime. In other words, you can use reflection to inspect metadata of the types in your program dynamically -- you can retrieve information on the loaded assemblies and the types defined in them.


1 Answers

After searching through Apples Documentation about objc Runtime and according to this SO answer I finally got it working. I just want to share my results.

unsigned int count;
objc_property_t* props = class_copyPropertyList([MyObject class], &count);
for (int i = 0; i < count; i++) {
    objc_property_t property = props[i];
    const char * name = property_getName(property);
    NSString *propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
    const char * type = property_getAttributes(property);
    NSString *attr = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];

    NSString * typeString = [NSString stringWithUTF8String:type];
    NSArray * attributes = [typeString componentsSeparatedByString:@","];
    NSString * typeAttribute = [attributes objectAtIndex:0];
    NSString * propertyType = [typeAttribute substringFromIndex:1];
    const char * rawPropertyType = [propertyType UTF8String];

    if (strcmp(rawPropertyType, @encode(float)) == 0) {
        //it's a float
    } else if (strcmp(rawPropertyType, @encode(int)) == 0) {
        //it's an int
    } else if (strcmp(rawPropertyType, @encode(id)) == 0) {
        //it's some sort of object
    } else {
        // According to Apples Documentation you can determine the corresponding encoding values
    }

    if ([typeAttribute hasPrefix:@"T@"]) {
        NSString * typeClassName = [typeAttribute substringWithRange:NSMakeRange(3, [typeAttribute length]-4)];  //turns @"NSDate" into NSDate
        Class typeClass = NSClassFromString(typeClassName);
        if (typeClass != nil) {
            // Here is the corresponding class even for nil values
        }
    }

}
free(props);
like image 82
Arndt Bieberstein Avatar answered Nov 15 '22 21:11

Arndt Bieberstein