2

Cocoa 是否提供内置方法来将键字符串转换为格式正确的 set 属性访问器?IE"lineSpacing" -> setLineSpacing:

例如:

NSString * key = @"lineSpacing";
SEL selector = [key magicallyConvertIntoSetPropertyAccessor];

甚至:

NSString * key = @"lineSpacing";
SEL selector = NSSelectorFromString([key toSetPropertyAccessor]);

背景:

我正在研究一种方法,该方法将使用存储在字典中的属性值按名称设置许多属性。我不能使用setObject:forKey,因为我也将此方法用于内置类型的属性,例如NSIntegerand 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”作为键调用上述方法会导致失败,因为正确的属性设置器将是setLineSpacing:而不是setLinespacing:

4

2 回答 2

5

您正在寻找setValue:forKey:,它不仅会找到正确的 setter 选择器,还会为您发送消息。它是键值编码协议的一部分;请注意,由于这个原因,getter likemyProperty和 setter likesetMyProperty:被称为“Key-Value-Coding-compliant”。

我正在研究一种方法,该方法将使用存储在字典中的属性值按名称设置许多属性。

另见方法,也是 KVC 协议的一部分setValuesForKeysWithDictionary:

于 2010-07-18T03:02:37.107 回答
1

Apple 并没有为此创建面向公众的函数,但通用算法非常简单:

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(我可能会补充一点,如果 a 的访问器设置为不同的东西,它将无法@property正常工作。我不知道 Objective-C 中的任何函数运行时,它将让您获得 a 的设置器@property。)

于 2010-07-18T03:19:49.063 回答