15

是否可以定义自己的关键路径运算符,例如@avg、@sum 等……</p>

4

2 回答 2

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!"

它有效,但我不确定我是否会依赖它,因为它依赖于未来可能会改变的实现细节。

于 2010-11-04T21:08:11.903 回答
0

可以通过在其中覆盖valueForKeyPath:并执行您自己的自定义逻辑来实现,但没有框架支持。

于 2010-11-04T20:09:20.717 回答