开发者

Defining your own key path operators in cocoa

Is it possible to define your own key path operators, such as @avg开发者_运维问答, @sum, etc…


Short answer: Kinda. You can override valueForKeyPath: to intercept your custom operator or forward on to super, but that can be problematic (I'll leave the explanation to that as an exercise to the reader).

Long answer: Yes you can, but it relies on using private behavior (not private api).

After some neat introspection of NSArray, I found some private methods:

_distinctUnionOfSetsForKeyPath:
_distinctUnionOfObjectsForKeyPath:
_distinctUnionOfArraysForKeyPath:
_unionOfSetsForKeyPath:
_unionOfArraysForKeyPath:
_unionOfObjectsForKeyPath:
_minForKeyPath:
_maxForKeyPath:
_countForKeyPath:
_avgForKeyPath:
_sumForKeyPath:

Well, neat! Those methods seem to match the operators you can use with collections: @sum, @min, @max, @distinctUnionOfObjects, etc. The @ has been replaced with an underscore and we've got ForKeyPath: appended.

So it would seem that we can create a new method to match the appropriate signature and we're good to go.

So:

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

It works, but I'm not sure I would rely on this, since it relies on an implementation detail that could change in the future.


It's possible by overriding valueForKeyPath: and doing your own custom logic in there, but there's no framework support for it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜