在NSObject子类上使用自动合成属性的键值编码:respondsToSelector为所有属性访问器返回NO?

ray*_*ray 0 objective-c key-value-coding ios7

我有一个NSObject带有一些属性的简单子类

@interface MyThing : NSObject
    @property (nonatomic, copy) NSString *aString;
    //... and so on
@end
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用键/值编码通过字典设置我的属性时:

+ (instancetype)thingFromDictionary:(NSDictionary *)dict
{
    MyThing *newThing = [MyThing new];
    for (NSString *key in dict)
    {
        if ([newThing respondsToSelector:@selector(key)])
        {
            //do stuff
            [newThing setValue:[dict objectForKey:key] forKey:key];
        }
        else
        {
            NSLog(@"key %@ doesnt exist. value %@", key, [dict objectForKey:key]);
        }
    }
    return newThing;
}
Run Code Online (Sandbox Code Playgroud)

事实证明,虽然字典包含与我的属性的确切名称匹配的键,但respondsToSelector:总是NO为这些键返回. 如何通过键/值方法确保可以访问所有属性?

Mar*_*n R 5

if ([newThing respondsToSelector:@selector(key)])
Run Code Online (Sandbox Code Playgroud)

检查对象是否响应选择器"key".参数@selector 是一个文字键而不是扩展.

要从字符串变量创建选择器,请使用NSSelectorFromString():

if ([newThing respondsToSelector:NSSelectorFromString(key)])
Run Code Online (Sandbox Code Playgroud)

但请注意,正如Gerd K在评论中正确陈述的那样,这将检查具有该名称的属性是否存在getter方法.要检查属性是否可以下注,您必须检查setter方法,(例如setAString:):

NSString *key = @"aString";
NSString *setter = [NSString stringWithFormat:@"set%@%@:", 
                    [[key substringToIndex:1] uppercaseString],
                    [key substringFromIndex:1]];
if ([newThing respondsToSelector:NSSelectorFromString(setter)])
...
Run Code Online (Sandbox Code Playgroud)