Objective c 在cocoa中定义自己的键路径操作符

Objective c 在cocoa中定义自己的键路径操作符,objective-c,cocoa,key-value-coding,Objective C,Cocoa,Key Value Coding,是否可以定义自己的关键路径运算符,如@avg、@sum等。可以覆盖valueForKeyPath:并在其中执行自己的自定义逻辑,但没有框架支持。简短回答:有点。您可以覆盖valueForKeyPath:以拦截自定义运算符或转发到super,但这可能会有问题(我将把解释留给读者作为练习) 详细回答:可以,但它依赖于使用私有行为(而不是私有api) 在仔细反省了一下NSArray之后,我发现了一些私有方法: _distinctUnionOfSetsForKeyPath: _distinctUnion

是否可以定义自己的关键路径运算符,如@avg、@sum等。

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

简短回答:有点。您可以覆盖
valueForKeyPath:
以拦截自定义运算符或转发到
super
,但这可能会有问题(我将把解释留给读者作为练习)

详细回答:可以,但它依赖于使用私有行为(而不是私有api)

在仔细反省了一下NSArray之后,我发现了一些私有方法:

_distinctUnionOfSetsForKeyPath:
_distinctUnionOfObjectsForKeyPath:
_distinctUnionOfArraysForKeyPath:
_unionOfSetsForKeyPath:
_unionOfArraysForKeyPath:
_unionOfObjectsForKeyPath:
_minForKeyPath:
_maxForKeyPath:
_countForKeyPath:
_avgForKeyPath:
_sumForKeyPath:
好的,太好了!这些方法似乎与可用于集合的运算符相匹配:
@sum
@min
@max
@distinctUnionOfObjects
,等等。已将
@
替换为下划线,并添加了
ForKeyPath:

因此,我们似乎可以创建一个新的方法来匹配适当的签名,我们就可以开始了

因此:


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

我必须不断克服向烹饪网站发送
cocoa
问题的冲动…+1这是一个非常吸引人的问题;一个我从来没有想过要问的问题,但它揭示了一些非常有趣的信息。谢谢你的邀请!重写
-valueForKey:
,尽管我会这样做。阅读有关NSDictionary如何实现它的文档。@Mike从长远来看,它可能更稳定,但重写的问题是,这些运算符通常只对集合有用,而对集合进行子类化有点糟糕(很高兴找到Dave!不过,正如你所说,这似乎是一个双刃剑。为什么你认为覆盖valueForKeyPath:更危险?@Fernando:与类别相比,对集合进行子类化是很棘手的,我还没有尝试过它,以了解其中涉及到什么。你是否需要编写特定的边缘案例?我不知道。类别y方法虽然看起来很脆弱,但对我来说似乎更简单。你也可以利用Matt Gallagher的分类技术,基本上允许你只对
-valueForKey:
进行分类
NSArray
。捕获你自己的自定义键路径操作符,然后将任何其他内容发送回“超序列”实现。
@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!"