避免嵌套 KVO 键路径中硬编码字符串的最佳方法
Best way to avoid hardcoded strings in nested KVO keypaths
当通过 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 的搜索没有找到解决这个特定问题的任何结果。
我还没有尝试过这个(甚至没有编译过),但你可以看看使用可变辅助方法:
+ (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:@"."];
}
我使用来自 libextobjc 的 EXTKeyPathCoding.h。您可以在 https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTKeyPathCoding.h
查看他们是如何做的
Swift 3 添加#keyPath()
以从"property chain".
生成关键路径字符串
let keyPathString = #keyPath(MyType.myProperty1.myProperty2)
函数内的标记不是字符串,将由编译器检查。
当通过 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 的搜索没有找到解决这个特定问题的任何结果。
我还没有尝试过这个(甚至没有编译过),但你可以看看使用可变辅助方法:
+ (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:@"."];
}
我使用来自 libextobjc 的 EXTKeyPathCoding.h。您可以在 https://github.com/jspahrsummers/libextobjc/blob/master/extobjc/EXTKeyPathCoding.h
查看他们是如何做的Swift 3 添加#keyPath()
以从"property chain".
let keyPathString = #keyPath(MyType.myProperty1.myProperty2)
函数内的标记不是字符串,将由编译器检查。