Patricia
Patricia

Reputation: 5089

Set property values of an Objective-C class using reflection

I am trying to learn reflection in Objective-C. I've found some great information on how to dump the property list of a class, especially here, but I want to know if it is possible to set a property's value using reflection.

I have a dictionary of keys (property names) and values (all NSStrings). I want to use Reflection to get the property and then set its value to the value in my dictionary. Is this possible? Or am I dreaming?

This has nothing to do with the dictionary. I am merely using the dictionary to send in the values.

Like this question, but for Objective C.

- (void)populateProperty:(NSString *)value
{
    Class clazz = [self class];
    u_int count;

    objc_property_t* properties = class_copyPropertyList(clazz, &count);
    for (int i = 0; i < count ; i++)
    {
        const char* propertyName = property_getName(properties[i]);
        NSString *prop = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
        // Here I have found my prop
        // How do I populate it with value passed in?
    }
    free(properties);

}

Upvotes: 5

Views: 5368

Answers (2)

jscs
jscs

Reputation: 64002

The NSKeyValueCoding protocol, which NSObject implements (see NSKeyValueCoding.h), contains the method -setValuesForKeysWithDictionary:. This method takes exactly the kind of dictionary you describe and sets the appropriate properties (or ivars) of the reciever.

This is absolutely reflection; the code in setValuesForKeysWithDictionary: accesses the properties by the names you give it, and will even find the appropriate ivar if no setter method exists.

Upvotes: 3

Fruity Geek
Fruity Geek

Reputation: 7381

Objective C properties automatically conform to the NSKeyValueCoding protocol. You can use setValue:forKey: to set any property value by a string property name.

NSDictionary * objectProperties = @{@"propertyName" : @"A value for property name",
                                    @"anotherPropertyName" : @"MOAR VALUE"};

//Assuming class has properties propertyName and anotherPropertyName
NSObject * object = [[NSObject alloc] init];

for (NSString * propertyName in objectProperties.allKeys)
{
    NSString * propertyValue = [objectProperties valueForKey:propertyName];

    [object setValue:propertyValue
              forKey:propertyName];
}

Upvotes: 13

Related Questions