Exception thrown in NSOrderedSet generated accessors

50,500

Solution 1

I reproduced your setup both with your data model and one of my own with different names. I got the same error in both cases.

Looks like a bug in Apple's autogenerated code.

Solution 2

I agree that there may be a bug here. I've modified the implementation of the add object setter to append correctly to a NSMutableOrderedSet.

- (void)addSubitemsObject:(SubItem *)value {
    NSMutableOrderedSet* tempSet = [NSMutableOrderedSet orderedSetWithOrderedSet:self.subitems];
    [tempSet addObject:value];
    self.subitems = tempSet;
}

Reassigning the set to self.subitems will ensure that the Will/DidChangeValue notifications are sent.

Solution 3

I've decided to improve the solution by implementing all the required methods:

static NSString *const kItemsKey = @"<#property#>";

- (void)insertObject:(<#Type#> *)value in<#Property#>AtIndex:(NSUInteger)idx {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet insertObject:value atIndex:idx];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)removeObjectFrom<#Property#>AtIndex:(NSUInteger)idx {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet removeObjectAtIndex:idx];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)insert<#Property#>:(NSArray *)values atIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet insertObjects:values atIndexes:indexes];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)remove<#Property#>AtIndexes:(NSIndexSet *)indexes {
    [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet removeObjectsAtIndexes:indexes];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)replaceObjectIn<#Property#>AtIndex:(NSUInteger)idx withObject:(<#Type#> *)value {
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet replaceObjectAtIndex:idx withObject:value];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)replace<#Property#>AtIndexes:(NSIndexSet *)indexes with<#Property#>:(NSArray *)values {
    [self willChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    [tmpOrderedSet replaceObjectsAtIndexes:indexes withObjects:values];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeReplacement valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)add<#Property#>Object:(<#Type#> *)value {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSUInteger idx = [tmpOrderedSet count];
    NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
    [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    [tmpOrderedSet addObject:value];
    [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
    [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
}

- (void)remove<#Property#>Object:(<#Type#> *)value {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSUInteger idx = [tmpOrderedSet indexOfObject:value];
    if (idx != NSNotFound) {
        NSIndexSet* indexes = [NSIndexSet indexSetWithIndex:idx];
        [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet removeObject:value];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

- (void)add<#Property#>:(NSOrderedSet *)values {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    NSUInteger valuesCount = [values count];
    NSUInteger objectsCount = [tmpOrderedSet count];
    for (NSUInteger i = 0; i < valuesCount; ++i) {
        [indexes addIndex:(objectsCount + i)];
    }
    if (valuesCount > 0) {
        [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet addObjectsFromArray:[values array]];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

- (void)remove<#Property#>:(NSOrderedSet *)values {
    NSMutableOrderedSet *tmpOrderedSet = [NSMutableOrderedSet orderedSetWithOrderedSet:[self mutableOrderedSetValueForKey:kItemsKey]];
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
    for (id value in values) {
        NSUInteger idx = [tmpOrderedSet indexOfObject:value];
        if (idx != NSNotFound) {
            [indexes addIndex:idx];
        }
    }
    if ([indexes count] > 0) {
        [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
        [tmpOrderedSet removeObjectsAtIndexes:indexes];
        [self setPrimitiveValue:tmpOrderedSet forKey:kItemsKey];
        [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:indexes forKey:kItemsKey];
    }
}

Solution 4

Yes, this is definitely a Core Data bug. I wrote up an ObjC-Runtime-based fix a while back, but at the time I figured it would be fixed soon. Anyway, no such luck, so I posted it up on GitHub as KCOrderedAccessorFix. Work around the problem on all your entities:

[managedObjectModel kc_generateOrderedSetAccessors];

One entity in particular:

[managedObjectModel kc_generateOrderedSetAccessorsForEntity:entity];

Or just for one relationship:

[managedObjectModel kc_generateOrderedSetAccessorsForRelationship:relationship];

Solution 5

Instead to making a copy I suggest to use the accessor in NSObject to get access to the NSMutableOrderedSet of the relationships.

- (void)addSubitemsObject:(SubItem *)value {
      NSMutableOrderedSet* tempSet = [self mutableOrderedSetValueForKey:@"subitems"];
      [tempSet addObject:value];
 }

e.g. the Core Data Release Notes for iOS v5.0 refer to this.

In a short test it worked in my application.

Share:
50,500
Dev
Author by

Dev

Updated on July 08, 2022

Comments

  • Dev
    Dev almost 2 years

    On my Lion app, I have this data model:

    enter image description here

    The relationship subitems inside Item is ordered.

    Xcode 4.1 (build 4B110) has created for me the file Item.h, Item.m, SubItem.h and SubItem.h.

    Here is the content (autogenerated) of Item.h:

    #import <Foundation/Foundation.h>
    
    #import <CoreData/CoreData.h>
    
    @class SubItem;
    
    @interface Item : NSManagedObject {
    @private
    }
    
    @property (nonatomic, retain) NSString * name;
    @property (nonatomic, retain) NSOrderedSet *subitems;
    @end
    
    @interface Item (CoreDataGeneratedAccessors)
    
    - (void)insertObject:(SubItem *)value inSubitemsAtIndex:(NSUInteger)idx;
    - (void)removeObjectFromSubitemsAtIndex:(NSUInteger)idx;
    - (void)insertSubitems:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
    - (void)removeSubitemsAtIndexes:(NSIndexSet *)indexes;
    - (void)replaceObjectInSubitemsAtIndex:(NSUInteger)idx withObject:(SubItem *)value;
    - (void)replaceSubitemsAtIndexes:(NSIndexSet *)indexes withSubitems:(NSArray *)values;
    - (void)addSubitemsObject:(SubItem *)value;
    - (void)removeSubitemsObject:(SubItem *)value;
    - (void)addSubitems:(NSOrderedSet *)values;
    - (void)removeSubitems:(NSOrderedSet *)values;
    
    @end
    

    And here is the content (autogenerated) of Item.m:

    #import "Item.h"
    #import "SubItem.h"
    
    @implementation Item
    
    @dynamic name;
    @dynamic subitems;
    
    @end
    

    As you can see, the class Item offers a method called addSubitemsObject:. Unfortunately, when trying to use it in this way:

    Item *item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.managedObjectContext];
    item.name = @"FirstItem";
    
    SubItem *subItem = [NSEntityDescription insertNewObjectForEntityForName:@"SubItem" inManagedObjectContext:self.managedObjectContext];
    
    [item addSubitemsObject:subItem];
    

    this error appear:

    2011-09-12 10:28:45.236 Test[2002:707] *** -[NSSet intersectsSet:]: set argument is not an NSSet
    

    Can you help me?

    Update:

    After just 1,787 days from my bug report, today (August 1, 2016) Apple wrote me this: "Please verify this issue with the latest iOS 10 beta build and update your bug report at bugreport.apple.com with your results.". Let's hope this is the right time :)

  • Dev
    Dev over 12 years
    Thanks. I filed a bug report.
  • Christopher Hujanen
    Christopher Hujanen over 12 years
    Your code snippet was just what I needed to get me around this issue. Hope Apple fixes the issue eventually, but so far I haven't seen any issues with using your approach.
  • Jacob
    Jacob over 12 years
    @Dev Thanks! Please provide bug number.
  • Sbhklr
    Sbhklr over 12 years
    +1 For the bug number. @Dev please provide it here. I does NOT seem to be fixed neither in 4.2.1 nor in XCode 4.3 Preview
  • Dev
    Dev over 12 years
    The bug ID is 10114310. It was reported on 13-Sep-2011 but today (15-Jan-2012) it is still "open". It is incredible, considering the number of people who have the same problem.
  • DerekH
    DerekH over 12 years
    Having the same issue, updated from Xcode 3 to 4.x.. It is very frustrating.
  • DerekH
    DerekH over 12 years
    I am getting this error when I try to implement this work-around.. [__NSArrayI isEqualToSet:]: unrecognized selector sent to instance... This usually is from a item that has been release, but can't find where, anyone run into this?
  • InitJason
    InitJason over 12 years
    For CoreData to return or take an NSOrderedSet object, multiple conditions have to be met as this started question has shown. Most common mistakes I see when people sharing my code have been a developer not running Lion. NSOrderedSets framework is not available on snowleopard. But yes, I have not seen this fail, though I am not sure this is best on performance. I'd guess this takes the whole set and replaces it instead of just inserting the desired record.
  • InitJason
    InitJason over 12 years
    @DerekH isEqualToSet is a method only NSSet has, so my guess is you've converted, created, or are treating a pointer as an NSArray before passing back to the NSManagedObject, which should if any reason be calling isEqualToOrderedSet to determine if the set needs to even change or be left as is.
  • DerekH
    DerekH over 12 years
    @Leelll thanks for the reply, actually in mine I am using NSSet instead of NSOrderableSet set.. My code looks the same except I replaced NSMutableOrderedSet with NSMutableSet.. I wouldn't have though there was a difference, but maybe there is?
  • DerekH
    DerekH over 12 years
    Also, it only happens if when I do [tempSet addObject:value].. If I comment this out and just do the creation of the Mutable with itself and then re-set it.. it works fine.. It doesn't error until after I re-set "property".
  • InitJason
    InitJason over 12 years
    @DerekH I'm not sure what the underlying properties of a NSManagedObject are for a un-ordered to-many relationship. But what is not buggy is using the auto-generated method "addSubitemObject" don't implement this method, only declare it.
  • Stephan
    Stephan over 12 years
    have same issue ... can you put the bug on openradar
  • Sebastian Hoffmann
    Sebastian Hoffmann over 12 years
    The bug is actually related to the ordered attribute since the auto generated functions are actually for NSSet not NSOrderedSet.
  • atticus
    atticus about 12 years
    Everyone should file a duplicate bug with Apple on this. Duplicate bugs are one of the main ways the Apple engineers gauge priority for bug fixes.
  • Robert
    Robert about 12 years
    Just as a warning, I have implemented this code and it worked fine, however, later I found that its very slow! Be warned if you are repeatedly calling this in a loop.
  • Robert
    Robert about 12 years
    As a follow up to my previous comment I have found a way to speed this up if you need to call addSubItemObject: repeatedly. See my answer below.
  • logancautrell
    logancautrell almost 12 years
    Can't refactor literal strings as easily. The compiler can type check self.subitems if you use code.
  • Ricardo
    Ricardo almost 12 years
    If I go to apple radar and write in problem id this: 10114310, it doesn't find the bug. IS it normal?
  • Ricardo
    Ricardo almost 12 years
    I'm using removeObjectFromSubitemsAtIndex but when I save the context, my program crashes. It seems the deleted object still exists. However if after removeObjectFromSubitemsAtIndex I call context deleteObject, when I save the context everything goes fine. Any idea? Thanks.
  • Dmitry Makarenko
    Dmitry Makarenko almost 12 years
    What is the crash type? 'removeObjectFromSubitemsAtIndex' doesn't delete these subitems, they still exist in your storage, it's just the way to remove the relationship between the objects.
  • Dev
    Dev almost 12 years
    Update: today (May 11, 2012) the bug #10114310 is still open, 241 days after my report (September 13, 2011). Unbelievable.
  • Damien
    Damien almost 12 years
    @Dev: I've a similar experience with this one and just hit it again. You would wonder how it got past testing given that it simply does not work!
  • acecapades
    acecapades almost 12 years
    Similar to what this guy did: dev.totodotnet.net/post/16894288540/…
  • Stephan
    Stephan almost 12 years
    @logancautrell yes this is correct. It depends on the priority of the specific use case. In general I focus on save resources especially in this case because this was just a workaround.
  • DaGaMs
    DaGaMs almost 12 years
    I just brought this up with an Apple engineer during one of the CoreData Lab sessions at WWDC. They acknowledge the issue and that it's a genuine bug, and from what I've seen it has the "critical" status, but of course there's no promise as to when they'll fix it. I don't think it'll be fixed in iOS6/Mountain Lion. I think it'd be good to duplicate this radar further. Currently it has about 25 dup's, the more the better!
  • DaGaMs
    DaGaMs almost 12 years
    For reference, here is my OpenRadar for the duplicate I entered: openradar.appspot.com/radar?id=1760411
  • j b
    j b over 11 years
    I've also raised this on Apple's bug tracker. OpenRadar duplicate: openradar.appspot.com/radar?id=1850415
  • Tin Can
    Tin Can over 11 years
    @nicerobot - dead link now :(
  • Καrτhικ
    Καrτhικ over 11 years
    Because mogenerator takes care of the extra code you would otherwise have to write and simply allows access to the underlying set object.
  • Dev
    Dev over 11 years
    Update: today (August 30, 2012) the bug #10114310 is still open. Almost a year has passed since my first report (September 13, 2011). Unbelievable.
  • Bagusflyer
    Bagusflyer over 11 years
    Seems Apple doesn't want to solve the problem. I still encounter the same problem today.
  • Bagusflyer
    Bagusflyer over 11 years
    what is kItemsKey? Is it the attribute name?
  • Bagusflyer
    Bagusflyer over 11 years
    And I add these methods in my program and did some updates, for example I called insertObject. But nothing happened in my Core Data.
  • Dmitry Makarenko
    Dmitry Makarenko over 11 years
    kItemsKey is a constant which was added just for convenience in KVO methods calls. It's a name of ordered relationship you are writing your methods for.
  • Bagusflyer
    Bagusflyer over 11 years
    That's what I think it is. Thanks. But my problem is that the data is not saved to database by using these methods.
  • Dmitry Makarenko
    Dmitry Makarenko over 11 years
    Did you call save: method of MOC you are using? Problem should not be in method I provided, as they are doing quite simple action, which definitely changes a state of NSManagedObject, most likely you are not calling save: or it returns with error.
  • jmstone617
    jmstone617 over 11 years
    Bug # 12476849 also filed on Radar for this issue
  • jmstone617
    jmstone617 over 11 years
    This gives the following error: '[<CLASS 0x20886d10> valueForUndefinedKey:]: this class is not key value coding-compliant for the key subitems.'
  • Dev
    Dev over 11 years
    Update: 442 days have passed since I filled the bug #10114310 and, guess what? Today (November 28, 2012) it is still open. I also believe that seems Apple doesn't want to solve the problem.
  • combinatorial
    combinatorial over 11 years
    It looks like a fix has just been committed that means mogenerator will generate corrected bodies ... github.com/dmakarenko/mogenerator/commit/…
  • pickwick
    pickwick over 11 years
    Why are you making a copy of the mutableOrderedSet, and then reassigning the primitive to it? I thought the whole point of the mutableOrderedSet is that you can affect it directly, and it will handle key/value notifications and relationships for you. (see developer.apple.com/library/mac/#documentation/Cocoa/Concept‌​ual/…)
  • Simon
    Simon over 11 years
    Still happening here, Jan '13.
  • Ricardo
    Ricardo over 11 years
    Simon, that's incredible. I use ordered relationships very often. Don't understand why apple don't fix it.
  • Scott Corscadden
    Scott Corscadden about 11 years
    Yup - still exists in iOS 6.1 too. Filed radar 13191471 against not having a "known issue" about this in the docs.
  • John Cromartie
    John Cromartie about 11 years
    Wouldn't it be simpler to just use the mutable set accessor?
  • iGranDav
    iGranDav about 11 years
    I've just filled a duplicate 13430690 just in case.
  • GreenKiwi
    GreenKiwi about 11 years
    Filed another duplicate, in the hopes that more will help get it fixed.
  • an0
    an0 almost 11 years
    After almost two years, Apple confirms this critical bug is still there: "This issue is still being investigated. If we have an update or need more information we will contact you." Wish they fix it in iOS 7.
  • tia
    tia almost 11 years
    I wonder if this will conflict with the real fix from Apple or not?
  • Colas
    Colas almost 11 years
    I am using mogenerator but I still have the bug.
  • Mark Amery
    Mark Amery almost 11 years
    Other reimplementations of Apple's broken methods, like the one here: stackoverflow.com/a/15994818/1709587 and the one here: dev.totodotnet.net/post/16894288540/… call willChangeValueForKey: and didChangeValueForKey:, respectively before and after adding the object, but this solution does not. Should it? I've never used either of those methods so I don't know when they're usually triggered or what they're typically used for.
  • InitJason
    InitJason almost 11 years
    @MarkAmery the dynamic setter self.subitems should be sending the notifications. Have you tested if it is not, or only wanted to know they the methods were not called from addSubitemsObject?
  • Mark Amery
    Mark Amery almost 11 years
    @JLust I haven't tested anything, or looked too closely at the code or docs - I just noticed that other people's approaches to this explicitly called them, and that yours doesn't, and wondered what the reason for the difference was and whether it was a mistake on anyone's part.
  • Scott Corscadden
    Scott Corscadden almost 11 years
    While it still irks me no end that this is not listed in Apple's known issues (I have opened a radar for the apparently futile gesture that it is), this solution has worked flawlessly for me.
  • Scott Corscadden
    Scott Corscadden almost 11 years
    How this is not listed as a "Known issue" utterly confounds me. If you use the type-safe auto generated methods, you're gonna have a bad time (/me ends rant)
  • marchinram
    marchinram almost 11 years
    Still happening for me, filed duplicate
  • bernstein
    bernstein over 10 years
    @MarkAmery Tested. Verified. The dynamic setter self.subitems does send the notifications. So JLust solution is correct.
  • rvijay007
    rvijay007 over 10 years
    I just had this same error and since I almost missed it, I wanted to point out @Sterling's github code below which beautifully fixes this problem. His repository is KCOrderedAccessorFix, and with one line of code, everything works as expected!
  • flypig
    flypig over 10 years
    !!!!!!!!! Just copying the code and change the method names, it works perfectly!!! This is the fastest answer.
  • an0
    an0 over 10 years
    Just checked today, it is still there in iOS 7 GM/OMG! I can't believe it…
  • Owen Godfrey
    Owen Godfrey over 10 years
    This is terrific, but creating the temporary copy of the ordered set is unnecessary. The culprit is willChangeValueForKey:withSetMutation:usingObjects, which you have successfully avoided. After that, just use [[self primitiveValueForKey:ChildrenKey] unionOrderedSet:values] or [[self primitiveValueForKey:ChildrenKey] minusOrderedSet:values] as appropriate. See my answer for details.
  • Owen Godfrey
    Owen Godfrey over 10 years
    This is a good answer, but its inefficient. You copy the entire ordered set, modify and then copy it back. The effect is not just a hit to the ordered set, but notifications are sent out that that every time the ordered set is altered, its entire contents are changed! If this ordered set is used for a UITable for instance, this could have serious ramifications for updating. I've outlined in my solution exactly where the error comes from and I've shown a more efficient method for bypassing the error.
  • BiGGA
    BiGGA over 10 years
    Awesome! I copied the codes and changed the variables a little. Works like a charm.
  • Johan S
    Johan S over 10 years
    This is very nice. It solves the whole problem and keeps it ordered aswell. Still insane that the bug is still present. Another benefit of this answer is that if you regenerate your core-data models you don't have to rewrite your bug fixes. Thanks!
  • Owen Godfrey
    Owen Godfrey over 10 years
    See my other answer. I tracked the bug in more detail. This is still the easiest way, but the other method is the best because it opens up more possibilities.
  • Vladimir Shutyuk
    Vladimir Shutyuk over 10 years
    Good point to move this code into category. But still we need to embrace actual add/remove with will/setPrimitiveValue/didChange calls like in @Dmitry Makarenko answer.
  • Dev
    Dev over 10 years
    Update: 797 days, 2 new major iOS versions, and countless Xcode versions have passed since I filled the bug #10114310. And it is still "open." Unbelievable.
  • George
    George over 10 years
    Too bad everyone else seems to have overlooked this answer, definitely seems like the best solution.
  • Sterling Archer
    Sterling Archer over 10 years
    This should not conflict with Apple's fix, as its purpose is to override Apple's implementation no matter what. When/if this is actually fixed by Apple, maybe I'll add a - (BOOL)kc_needsOrderedSetAccessorFix; or something that checks Foundation/iOS version.
  • Anton Matosov
    Anton Matosov about 10 years
    There is a KCOrderedAccessorFix.podspec already in the CocoaPods master repo. So in order to link this to your projects you can simply add "pod 'KCOrderedAccessorFix'" to your Podfile
  • Leonard Pauli
    Leonard Pauli about 10 years
    Wow! Finally!!! Thanks! (Tried your other code, but got errors, something about that wrong type was sent at [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:indexSet forKey:ChildrenKey];)
  • David Pettigrew
    David Pettigrew almost 10 years
    This solution has much better performance than the ones using orderedSetWithOrderedSet to make a local set. That has a big overhead when you have large data sets. The easier solution appears to just be a refactored version of the initial one with the methods not shown.
  • fatuhoku
    fatuhoku almost 10 years
    Doesn't do much good when both sides are to-many. Then there's no clear parent-child relationship.
  • Andy Tsen
    Andy Tsen almost 10 years
    I cannot believe this. Just hit this right now. Spend an entire day debugging because I thought I had a flaw in my add logic. Thanks Crapple.
  • Ja͢ck
    Ja͢ck almost 10 years
    The literal string may be replaced by NSStringFromSelector(@selector(subitems)) though :)
  • ruandao
    ruandao almost 10 years
    still get it...so terrible
  • Ezimet
    Ezimet over 9 years
    Does apple know about this bug ?? I just hit the same problem on iOS8 beta 5, Xcode 6 b6.
  • Dev
    Dev over 9 years
    Update: Happy 3rd birthday! The NSOrderedSet's bug turned three two days ago :)
  • Carlos P
    Carlos P over 9 years
    Welcome to iOS 8 GM, little bug.
  • Dănuț Mihai Florian
    Dănuț Mihai Florian over 9 years
    Update: It's still open!
  • Nicolas Manzini
    Nicolas Manzini over 9 years
    well actually one should use mutableOrderedSetValueForKey as mentioned here stackoverflow.com/a/26676124/926899
  • iphone007
    iphone007 over 9 years
    Hmmm, I tried this solution but the changes don't appear to be saved (after calling saveContext).
  • iphone007
    iphone007 over 9 years
    Hmmm, my code is not exactly the same now but it works under iOS 7.1 in the simulator but doesn't work under iOS 8.1 in the simulator. :-(
  • Matt
    Matt over 9 years
    To be fair, the docs also say: "or one of the automatically-generated relationship mutator methods (see Dynamically-Generated Accessor Methods):"
  • Nicolas Manzini
    Nicolas Manzini over 9 years
    Okay okay... you're right. Well then, let's say that that's the simplest working way...
  • Ja͢ck
    Ja͢ck over 9 years
    Wish I had seen this answer earlier; I was using the highest voted answer until I recently did some digging and finally implemented exactly what you have here :)
  • NSTJ
    NSTJ over 9 years
    This had some issues with iOS 8 (incorrect method signatures for objc_msg_send)
  • CarmeloS
    CarmeloS over 9 years
    I met this problem in late 2012 and I searched to this question, now it is 2015, in iOS 8, the bug still exist, I will leave a comment every time I bump into this bug in the rest of my life!!!!!!!
  • Alexander Perechnev
    Alexander Perechnev about 9 years
    February 9th, 2015. Still isn't fixed. AppLOL :)
  • Anton Ogarkov
    Anton Ogarkov about 9 years
    Just got this bug in my code. It is March 27th. Apple in a nutshell indeed.
  • pronebird
    pronebird almost 9 years
    I used a KCOrderedAccessorFix to fix this which broke with 64bit runtime. FML.
  • andykkt
    andykkt almost 9 years
    It looks like still happening. May 31, 2015
  • Victor Bogdan
    Victor Bogdan almost 9 years
    I'm still seeing a crash in addChildren: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TrackHistory insertTrackpoints:atIndexes:]: unrecognized selector sent to instance 0x1702b1b20'
  • an0
    an0 almost 9 years
    Hey guys, I'm still here with you, in iOS 9!
  • adamF
    adamF almost 9 years
    This is sad apple, after almost 4 years, the bug still exists in a central piece of core data
  • Dalmazio
    Dalmazio over 8 years
    @OwenGodfrey For the easier solution, where are you implementing these methods? I'm getting an exception: [Parent insertObject:inChildrenAtIndex:] unrecognized selector sent to instance 0x6180000ac480.
  • Owen Godfrey
    Owen Godfrey over 8 years
    your variable is "Parent" with a capital "P"? Does that means you are call the the class "Parent", or do you have an instance variable named "Parent"? If my class is Parent, then i implemented this methods at the bottom of Parent, but you would need to call it on an instance, which would more likely be named "parent" with a lowercase "p", as these are not class methods.
  • Borzh
    Borzh over 8 years
    On iOS9 it works, nice job! This is the best solution ever, no need to change anything in your code!
  • Ky -
    Ky - over 8 years
    So, if I cannot implement the other fixes, what should I do to fix this?
  • Jason Moore
    Jason Moore about 8 years
    Why is addObject: called twice?
  • CommaToast
    CommaToast about 8 years
    Strikes again. Come on guys
  • Tommaso Resti
    Tommaso Resti almost 8 years
    That's incredible...... Dear Apple, can you tell me how to insert/add an element on my NSOrderedSet?????
  • an0
    an0 almost 8 years
    Just verified it is still in iOS 10 beta 2. That's 5 years! I'm totally baffled.
  • Etep
    Etep almost 8 years
    I get the same error as Dalmazio Brisinda. It seems the category functions are not accessible from the main class? I have MyObject and MyObject+CoreDataProperties. I put all this code into MyObject (with the changes necessary (Children->MyObject) but I get the same exception. I'm guessing this must have to go into the Category in order to work but then each time I make a change to my Core Data Object this will get overwritten.
  • Etep
    Etep almost 8 years
    Great Answer!!! This should be the accepted answer with notes about the Apple bug. Tried a bunch of different versions from others that didn't work. This worked perfectly! Thank you!!!
  • Dev
    Dev almost 8 years
    Update: after just 1,787 days from my bug report, today (August 1, 2016) Apple wrote me this: "Please verify this issue with the latest iOS 10 beta build and update your bug report at bugreport.apple.com with your results.". Let's hope this is the right time :)
  • Morrowless
    Morrowless over 7 years
    Fixed in iOS 10! NSManagedObject dynamic accessor generation has fixed issues to properly generate accessors for ordered to-many relationships. developer.apple.com/library/prerelease/content/releasenotes/‌​…
  • Krypt
    Krypt almost 5 years
    2019: iOS 12 I got this bug again.