Reputation: 5089
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 NSString
s). 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
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
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