On my Lion app, I have this data model:
The relationship subitem
I think everybody is missing the real problem. It is not in the accessor methods but rather in the fact that NSOrderedSet
is not a subclass of NSSet
. So when -interSectsSet:
is called with an ordered set as argument it fails.
NSOrderedSet* setA = [NSOrderedSet orderedSetWithObjects:@"A",@"B",@"C",nil];
NSSet* setB = [NSSet setWithObjects:@"C",@"D", nil];
[setB intersectsSet:setA];
fails with *** -[NSSet intersectsSet:]: set argument is not an NSSet
Looks like the fix is to change the implementation of the set operators so they handle the types transparently. No reason why a -intersectsSet:
should work with either an ordered or unordered set.
The exception happens in the change notification. Presumably in the code that handles the inverse relationship. Since it only happens if I set an inverse relationship.
The following did the trick for me
@implementation MF_NSOrderedSetFixes
+ (void) fixSetMethods
{
NSArray* classes = [NSArray arrayWithObjects:@"NSSet", @"NSMutableSet", @"NSOrderedSet", @"NSMutableOrderedSet",nil];
[classes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString* name = obj;
Class aClass = objc_lookUpClass([name UTF8String]);
[MF_NSOrderedSetFixes fixMethodWithSetArgument:@selector(intersectsSet:) forClass:aClass];
[MF_NSOrderedSetFixes fixMethodWithSetArgument:@selector(isSubsetOfSet:) forClass:aClass];
}];
}
typedef BOOL (*BoolNSetIMP)(id _s,SEL sel, NSSet*);
/*
Works for all methods of type - (BOOL) method:(NSSet*) aSet
*/
+ (void) fixMethodWithSetArgument:(SEL) aSel forClass:(Class) aClass
{
/* Check that class actually implements method first */
/* can't use get_classInstanceMethod() since it checks superclass */
unsigned int count,i;
Method method = NULL;
Method* methods = class_copyMethodList(aClass, &count);
if(methods) {
for(i=0;i