2014-08-28 62 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