Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa是否提供内置方法将密钥转换为';设置';属性访问器?_Cocoa_Nsstring_Properties_Accessor - Fatal编程技术网

Cocoa是否提供内置方法将密钥转换为';设置';属性访问器?

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

Cocoa是否提供内置方法将密钥字符串转换为格式正确的集合属性访问器?i、 e.
“行距”->设置行距:

例如:

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:
会知道这一点,这是最好的方法。