Cocoa是否提供内置方法将密钥转换为';设置';属性访问器?
Cocoa是否提供内置方法将密钥字符串转换为格式正确的集合属性访问器?i、 e.Cocoa是否提供内置方法将密钥转换为';设置';属性访问器?,cocoa,nsstring,properties,accessor,Cocoa,Nsstring,Properties,Accessor,Cocoa是否提供内置方法将密钥字符串转换为格式正确的集合属性访问器?i、 e.“行距”->设置行距: 例如: NSString * key = @"lineSpacing"; SEL selector = [key magicallyConvertIntoSetPropertyAccessor]; 甚至: NSString * key = @"lineSpacing"; SEL selector = NSSelectorFromString([key toSetPropertyAccesso
“行距”->设置行距:
例如:
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];
}
此方法适用于“color”或“width”等单字属性,但对“linespace”或“meaningofiletheuniverseandeverything”等多字属性无效,因为
大写方法将第一个字母大写,同时将所有后续字母设置为小写。使用“lineSpacing”作为键调用上述方法会导致失败,因为正确的属性设置器将是setLineSpacing:
,而不是setLineSpacing:
您正在查找setValue:forKey:
,它不仅会找到正确的设置器选择器,还会为您发送消息。这是我的一部分;注意,由于这个原因,像myProperty
这样的getter和像setMyProperty:
这样的setter被称为“Key-Value-Coding-compliant”
我正在研究一种方法,该方法将使用字典中存储的属性值按名称设置许多属性
另请参见KVC协议的一部分。苹果公司尚未推出面向公众的功能来实现这一点,但通用算法非常简单:
SEL SetterSelectorForKey(NSString *key) {
SEL result = 0;
NSString *strFirstCharacter = [[key substringToIndex: 1] uppercaseString];
NSString *strRemainder = [key substringFromIndex: 1];
result = NSSelectorFromString([NSString stringWithFormat: @"set%@%@:", strFirstCharacter, strRemainder]);
return result;
}
然而,在你使用它之前,请记住,可能还有其他方法来实现你的目标。在开始之前,请调查您正在使用的现有API并执行此操作(我可能会补充,如果@property
的访问器设置为不同的值,则无法正常工作)。我不知道Objective-C运行时中有任何函数可以让您获得@property
的设置器)啊,对不起,我应该说得更具体些。这适用于对象样式特性,但不适用于基本体类型。我发布了setProperty方法的简化版本,但实际的方法使用了NSInvocation
,这需要更复杂的设置。詹姆斯:为什么不直接实现setFloatProperty:forKey:target:
方法将值框起来并传递给setValue:forKey:
?这比尝试复制KVC的算法要简单得多。(如果您担心性能,请记住他们关于过早优化的说法。您应该先用更简单的方法进行优化,然后对其进行分析,看看是否会让您陷入困境。)我不知道您可以发送NSNumber
来设置基元类型。这将使事情简化很多。谢谢你们两位@e、 James yep,如果目标是void*
或struct或更“C-ish”的东西,您也可以发送NSValue
对象:)@Dave DeLong:Beautiful。我也需要这样做。再次感谢:)
虽然这通常有效,但您可以使用属性语法指定自定义setter名称:@property(setter=setMyFoo:,getter=isMyFoo)BOOL foo代码>setValue:forKey:
会知道这一点,这是最好的方法。