是否可以定义自己的密钥路径运算符,例如@ avg,@ sum等...
答案 0 :(得分:14)
简短回答:有点儿。您可以覆盖valueForKeyPath:
来拦截您的自定义运算符或转发到super
,但这可能会有问题(我会将解释作为练习留给读者)。
答案很长:是的,你可以,但它依赖于使用私人行为(不是私人api)。
经过对NSArray
的一些巧妙的反省,我找到了一些私有方法:
_distinctUnionOfSetsForKeyPath:
_distinctUnionOfObjectsForKeyPath:
_distinctUnionOfArraysForKeyPath:
_unionOfSetsForKeyPath:
_unionOfArraysForKeyPath:
_unionOfObjectsForKeyPath:
_minForKeyPath:
_maxForKeyPath:
_countForKeyPath:
_avgForKeyPath:
_sumForKeyPath:
好吧,整洁!这些方法似乎与您可以用于集合的运算符相匹配:@sum
,@min
,@max
,@distinctUnionOfObjects
等。@
已被替换为下划线,我们附加了ForKeyPath:
。
所以看起来我们可以创建一个匹配相应签名的新方法,我们很高兴。
所以:
@interface NSArray (CustomOperator)
- (id) _fooForKeyPath:(NSString *)keyPath;
@end
@implementation NSArray (CustomOperator)
- (id) _fooForKeyPath:(NSString *)keyPath {
//keyPath will be what comes after the keyPath. In this example, it will be "self"
return @"Hello world!";
}
@end
NSArray * array = [NSArray arrayWithObjects:@"1", @"2", @"3", nil];
NSLog(@"%@", [array valueForKeyPath:@"@foo.SELF"]); //logs "Hello world!"
它有效,但我不确定我会依赖它,因为它依赖于将来可能会改变的实现细节。
答案 1 :(得分:0)
可以通过覆盖valueForKeyPath:
并在那里做自己的自定义逻辑,但是没有框架支持。