2014-08-28 59 views
3

我正在尝试学习Objective-C中的反射。我发现了一些关于如何转储一个类的属性列表的很好的信息,尤其是here,但我想知道是否可以使用反射设置属性的值。使用反射设置Objective-C类的属性值

我有一个键(属性名称)和值的字典(所有NSString s)。我想用Reflection来获取属性,然后将其值设置为我的字典中的值。这可能吗?还是我在做梦?

这与字典无关。我只是使用字典来发送值。

this question,但是对于目的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); 

} 

回答

13

目标C属性自动符合NSKeyValueCoding协议。您可以使用setValue:forKey:通过字符串属性名称设置任何属性值。

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]; 
} 
+0

这是反射。当您使用此方法时,会调用属性mutator和访问器。 – 2014-08-28 15:20:25

+3

@Lucy ['setValue:forKey:'](https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/Protocols/NSKeyValueCoding_Protocol/Reference/Reference.html#//apple_ref/doc/ uid/20000471-BABEHECF)是'NSObject'符合的'NSKeyValueCoding'协议的一部分。它与字典无关;你正在考虑'setObject:forKey:',它是'NSMutableDictionary'上的一个方法。 – 2014-08-28 16:09:41

+1

@Lucy'setValue:forKey:'跳过一堆箍,找到setter,然后调用它。这是反思。这通常是要避免的。 – bbum 2014-08-29 20:50:44

2

NSKeyValueCoding的协议,该协议NSObject器械(见NSKeyValueCoding.h),包含方法-setValuesForKeysWithDictionary:。此方法采用您描述的字典的种类,并设置接收器的适当属性(或ivars)。

这绝对是反思; setValuesForKeysWithDictionary:中的代码按照您提供的名称访问属性,如果不存在setter方法,它甚至会找到适当的ivar。

+2

这是反思;仅仅因为你没有写反射代码并不意味着它不是这样。 – 2014-08-28 18:46:41