Exception thrown in NSOrderedSet generated accessors

后端 未结 25 2548
天涯浪人
天涯浪人 2020-11-22 09:07

On my Lion app, I have this data model:

\"enter

The relationship subitem

25条回答
  •  孤城傲影
    2020-11-22 09:23

    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

提交回复
热议问题