Cocoa是否提供了一个内置的方法来将密钥字符串转换为正确格式的属性访问器?即"lineSpacing" -> setLineSpacing:
Cocoa是否提供了一个内置的方法来将密钥转换为'set'属性访问器?
例如:
NSString * key = @"lineSpacing";
SEL selector = [key magicallyConvertIntoSetPropertyAccessor];
甚至:
NSString * key = @"lineSpacing";
SEL selector = NSSelectorFromString([key toSetPropertyAccessor]);
背景:
我工作,将设置了许多特性的方法,通过名称,使用存储在字典中的属性值。我不能使用setObject:forKey
,因为我也使用这种方法的内置类型的属性,如NSInteger
和CGFloat
。这是我使用CGFloat的方法的一个例子,来说明:
- (void)setFloatProperty:(NSString *)key value:(CGFloat)value target:(id)object
{
NSString * setPropertyString = [NSString stringWithFormat:@"set%@",
[key capitalizedString]];
SEL selector = NSSelectorFromString(setPropertyString);
NSMethodSignature * signature = ...
NSInvocation * invocation = ...
CGFloat arg = value;
void * argument = &arg;
[invocation setArgument:argument atIndex:2];
[invocation invoke];
}
此方法适用于像“颜色”或“宽度”一个字的属性,但是未能在多功能使用词的属性,如“lineSpacing”或“meaningOfLifeTheUniverseAndEverything”,因为capitalize
方法将首字母大写,而将所有后续字母设置为小写。呼叫使用“lineSpacing”作为失败的关键结果上面的方法,因为正确的属性setter会setLineSpacing:
而不是setLinespacing:
啊,对不起,我应该更具体。这适用于对象样式属性,但不适用于基元类型。我发布了我的setProperty方法的简化版本,但实际使用的是'NSInvocation',它需要更复杂的设置。我会改变我的问题来说清楚。 – 2010-07-18 03:05:48
@ e.James它可以处理基元:http://pastie.org/1049035 – 2010-07-18 03:24:40
e.James:为什么不只是实现你的'setFloatProperty:forKey:target:'方法来填充值并将其传递给'setValue :forKey:'?这会比尝试复制KVC的算法简单得多。 (如果您担心性能,请记住他们对过早优化的看法,您应该先以更简单的方式进行操作,然后对其进行配置,看看它是否让您陷入困境。) – 2010-07-18 03:26:09