Skip to content

Instantly share code, notes, and snippets.

@n-b
Created November 22, 2012 15:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n-b/4131671 to your computer and use it in GitHub Desktop.
Save n-b/4131671 to your computer and use it in GitHub Desktop.
NSOrderedSet KVO Collection Operators tests
//
// clang orderedset-kvo-test.m -framework Foundation && ./a.out
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
int main ()
{
@autoreleasepool {
id collection = [NSOrderedSet orderedSetWithArray:
@[
@{@"values": @[@1, @2]},
@{@"values": @[@3, @4]},
@{@"values": @[@1, @3]},
]
];
@try {
NSLog(@"union : %@",[collection valueForKeyPath:@"@distinctUnionOfArrays.values"]);
} @catch (id e) { NSLog(@"crash : %@",e); }
/*
Dynamically add this method :
@implementation NSOrderedSet
- (id) _distinctUnionOfArraysForKeyPath:(NSString*) keyPath
{
return [[self array] _distinctUnionOfArraysForKeyPath:keyPath];
}
@end
*/
SEL selector = @selector(_distinctUnionOfArraysForKeyPath:);
class_addMethod([NSOrderedSet class],
selector,
imp_implementationWithBlock(^ (id self, NSString* keyPath)
{
return objc_msgSend([self array], selector, keyPath);
}),
method_getTypeEncoding(class_getInstanceMethod([NSArray class],selector)));
// This works now !
NSLog(@"union : %@",[collection valueForKeyPath:@"@distinctUnionOfArrays.values"]);
}
return 0;
}
> clang orderedset-kvo-test.m -framework Foundation && ./a.out && rm a.out
2012-11-22 18:25:03.035 a.out[67891:707] crash : [<__NSOrderedSetI 0x7f8050c0d0d0> valueForKeyPath:]: this class does not implement the distinctUnionOfArrays operation.
2012-11-22 18:25:03.037 a.out[67891:707] union : (
3,
2,
1,
4
)
@baarde
Copy link

baarde commented Nov 22, 2012

What about implementing private methods?

@implementation NSOrderedSet (MyKeyValueCoding)

- (id)_distinctUnionOfArraysForKeyPath:(NSString *)keyPath
{
    return [[self array] valueForKeyPath:[NSString stringWithFormat:@"@distinctUnionOfArrays.%@", keyPath]];
}

@end

@baarde
Copy link

baarde commented Nov 22, 2012

The problem with @array.@distinctUnionOfArrays.values is that KVC detects the period after @array and then try to use it as a collection operation (which is not implemented) before looking for the existence of the array method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment