在cocoa中定义自己的关键路径运算符

时间:2010-11-04 19:26:45

标签: objective-c cocoa key-value-coding

是否可以定义自己的密钥路径运算符,例如@ avg,@ sum等...

2 个答案:

答案 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:并在那里做自己的自定义逻辑,但是没有框架支持。