避免嵌套KVO密钥路径中硬编码字符串的最佳方法

时间:2015-04-02 20:00:10

标签: objective-c key-value-observing

当注册通过KVO观察对象时,我编写此代码以避免硬编码字符串:

[myObject addObserver:self
           forKeyPath:NSStringFromSelector(@selector(myProperty))
              options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
              context:NULL];

注意NSStringFromSelector。如果我更改myProperty的名称并忘记我有一些东西在观察它,它会在编译时保护我。

但是使用嵌套属性时情况会更复杂,例如" myProperty1.myProperty2"

我天真的解决方案是使用如下的宏:

#define KEYPATHSTRING1(a) NSStringFromSelector(@selector(a))
#define KEYPATHSTRING2(a, b) [NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(a)), NSStringFromSelector(@selector(b))]
#define KEYPATHSTRING3(a, b, c) [NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(a)), NSStringFromSelector(@selector(b)), NSStringFromSelector(@selector(c))]

那里有更好的或标准化的解决方案吗?对Google和SO的搜索没有找到解决这个问题的任何内容。

3 个答案:

答案 0 :(得分:2)

我没试过这个(甚至编译它),但你可以看一下使用可变参数辅助方法:

+ (NSString *)keyPathFromSelectors:(SEL)firstArg, ...
{
    NSMutableArray *keys = [NSMutableArray array];

    va_list args;
    va_start(args, firstArg);

    for (SEL arg = firstArg; arg != nil; arg = va_arg(args, SEL))
    {
        [keys addObject:NSStringFromSelector(arg)];
    }

    va_end(args);

    return [keys componentsJoinedByString:@"."];
}

答案 1 :(得分:1)

我使用libextobjc中的EXTKeyPathCoding.h。您可以在https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTKeyPathCoding.h

查看他们的行为方式

答案 2 :(得分:0)

Swift 3添加Exception: Error when checking model input: expected lstm_input_1 to have 3 dimensions, but got array with shape (21, 1) 以从"属性链生成关键路径字符串"。

#keyPath()

函数内的标记是而不是字符串,将由编译器检查。