KCOrderedAccessorFix
KCOrderedAccessorFix copied to clipboard
Q: Is KCOrderedAccessorFix still needed? (A: not on 10.12 or later)
Hello. This is a question - but I don't know how to tag it so. I am using KCOrderedAccessorFix in my 2014 Obj-C project, and it has been serving me well. I am now required to overhaul my project, adapt to latest OS-X SDK, add features etc. Do you (the writers) know if this fix is still needed? Hasn't Apple resolve their issue already in later OS versions / CoreData versions?
Is there a recommended way to determine this? (say remove your code from the build, and call something at the debugger level that will tell me if needed accessors exist)?
Did Apple improve their (rather lousy) support of Ordered-Sets elsewhere (binding, ArrayControllers etc.) ?
And if so - how can I conditionally add your code, so that it will only run on older OS versions?
Thanks.
Well, it may be of benefit to others reading my question, that @CFKevinRef and I verified that Apple has fixed this long-standing issue in Mac OS 10.12, so there is no need to use this extension when running on 10.12 or later. However - to have your app deployed for earlier versions, it is recommended to do something like this:
`- (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) return _managedObjectModel; // model already created - return it.
// first access - create model
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12)
return [super managedObjectModel]; // on new OS - revert to superclass implementation.
// on older OS - first create the model
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]];
// then fix the ordered relationships accessors using KCOrderedAccessorFix
[_managedObjectModel kc_generateOrderedSetAccessors];
// return the newly created model
return _managedObjectModel;
} `
I just attempted to remove KCOrderedAccessorFix from my project, and unfortunately, it seems like there are still issues. Specifically, the - (void)insert<Key>:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
selector does not seem to be implemented by Core Data. I haven't checked any of the others.
I'm using Xcode 11.0 with the latest macOS SDK.
Thanks very much!
Where and how have you hit into a problem by CoreData not generating this method?
Have you hit a crash when something assumed the existence of the method?
My project is striving to almost no code related to CoreData — most everything in my project is just sophisticated bindings between CoreData contexts and entities, to Interface-builder controllers and views. Since on these bindings I do not know which selectors are used by the implementation of, say, NSArrayController, or NSTableColumn — especially when “filters” (Predicates) and other things are involved — I’m worried that maybe my app may crash because of this lacuna.
Can you share your experience?
In my project, I put KCOrderedAccessorFix to action depending on the OS-X version I’m running on. I have not received crash reports from users.
Here is my usage in my Document subclass implementation:
-
(NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) return _managedObjectModel; // model already created - return it.
// first access - create model if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) return [super managedObjectModel]; // on new OS - revert to superclass implementation.
// on older OS - first create the model _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]];
// then fix the ordered relationships accessors using NSManagedObjectModel+KCOrderedAccessorFix [_managedObjectModel kc_generateOrderedSetAccessors];
// now return the newly created model return _managedObjectModel; }
Motti Shneor, CEO, Tchelet Technologies LTD. Software Development for Apple Platforms
Address: 34 Emek-Ha-Ella St. Appt.1 Modiin, ISRAEL, 7173147 Tel/Fax: +972-8-9267730 eMail: [email protected] Mobile phone: +972-54-3136621
ceterum censeo microsoftiem delendam esse
On 25 Sep 2019, at 21:21, Chris Vasselli [email protected] wrote:
I just attempted to remove KCOrderedAccessorFix from my project, and unfortunately, it seems like there are still issues. Specifically, the - (void)insert<Key>:(NSArray *)value atIndexes:(NSIndexSet *)indexes; selector does not seem to be implemented by Core Data. I haven't checked any of the others.
I'm using Xcode 11.0 with the latest macOS SDK.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CFKevinRef/KCOrderedAccessorFix/issues/16?email_source=notifications&email_token=AAUGO25UOAHWJMUKYTMZ7I3QLOT3TA5CNFSM4EKBKXCKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7S3VBI#issuecomment-535149189, or mute the thread https://github.com/notifications/unsubscribe-auth/AAUGO24WBCLL7ID4H2RWNIDQLOT3TANCNFSM4EKBKXCA.
I put together a little test.
I have a type KanjiEntry
in my app, that has an ordered to-many relationship called readings
to a type called KanjiEntryReading
.
Core data automatically generates a header with the following methods on KanjiEntry
related to this relationship:
- (void)insertObject:(KanjiEntryReading *)value inReadingsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromReadingsAtIndex:(NSUInteger)idx;
- (void)insertReadings:(NSArray<KanjiEntryReading *> *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeReadingsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInReadingsAtIndex:(NSUInteger)idx withObject:(KanjiEntryReading *)value;
- (void)replaceReadingsAtIndexes:(NSIndexSet *)indexes withReadings:(NSArray<KanjiEntryReading *> *)values;
- (void)addReadingsObject:(KanjiEntryReading *)value;
- (void)removeReadingsObject:(KanjiEntryReading *)value;
- (void)addReadings:(NSOrderedSet<KanjiEntryReading *> *)values;
- (void)removeReadings:(NSOrderedSet<KanjiEntryReading *> *)values;
I setup the following code to test which of these are actually implemented:
NSArray<NSString*>* selectors = @[
NSStringFromSelector(@selector(insertObject:inReadingsAtIndex:)),
NSStringFromSelector(@selector(removeObjectFromReadingsAtIndex:)),
NSStringFromSelector(@selector(insertReadings:atIndexes:)),
NSStringFromSelector(@selector(removeReadingsAtIndexes:)),
NSStringFromSelector(@selector(replaceObjectInReadingsAtIndex:withObject:)),
NSStringFromSelector(@selector(replaceReadingsAtIndexes:withReadings:)),
NSStringFromSelector(@selector(addReadingsObject:)),
NSStringFromSelector(@selector(removeReadingsObject:)),
NSStringFromSelector(@selector(addReadings:)),
NSStringFromSelector(@selector(removeReadings:))
];
for ( NSString* selector in selectors )
{
if ( [entry respondsToSelector:NSSelectorFromString(selector)] )
NSLog(@"%@ exists.", selector);
else
NSLog(@"%@ does not exist.", selector);
}
The results were:
insertObject:inReadingsAtIndex: exists.
removeObjectFromReadingsAtIndex: exists.
insertReadings:atIndexes: does not exist.
removeReadingsAtIndexes: exists.
replaceObjectInReadingsAtIndex:withObject: exists.
replaceReadingsAtIndexes:withReadings: does not exist.
addReadingsObject: exists.
removeReadingsObject: exists.
addReadings: exists.
removeReadings: exists.
So it looks like insertReadings:atIndexes:
and replaceReadingsAtIndexes:withReadings:
were not actually generated by Core Data.
This is a rather sad find. I wonder what happened at Apple - like this is a decade-standing issue, that was already addressed once - Why is it breaking? Why don’t they implement it once and for all? OrderedSets are so old now — It seems like CoreData is decaying for incompatibility with the new fashionable technologies that don’t go the Cocoa-bindings (KVC/KVO) way. Maybe anything un-swifty gets neglected?
By any means, this should be reported a s a new bug on coreData - and you have just the sample-code they require as proof of the bug.
Moreover - since you say CoreData generates the headers for these unimplemented methods — it means they already obliged to implementing them, and we can expect a fix sometime.
Have you opened a Radar bug already?
Motti Shneor, CEO, Tchelet Technologies LTD. Software Development for Apple Platforms
ceterum censeo microsoftiem delendam esse
On 26 Sep 2019, at 17:08, Chris Vasselli [email protected] wrote:
I put together a little test.
I have a type KanjiEntry in my app, that has an ordered to-many relationship called readings to a type called KanjiEntryReading.
Core data automatically generates a header with the following methods on KanjiEntry related to this relationship:
- (void)insertObject:(KanjiEntryReading *)value inReadingsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromReadingsAtIndex:(NSUInteger)idx;
- (void)insertReadings:(NSArray<KanjiEntryReading *> *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeReadingsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInReadingsAtIndex:(NSUInteger)idx withObject:(KanjiEntryReading *)value;
- (void)replaceReadingsAtIndexes:(NSIndexSet *)indexes withReadings:(NSArray<KanjiEntryReading *> *)values;
- (void)addReadingsObject:(KanjiEntryReading *)value;
- (void)removeReadingsObject:(KanjiEntryReading *)value;
- (void)addReadings:(NSOrderedSet<KanjiEntryReading *> *)values;
- (void)removeReadings:(NSOrderedSet<KanjiEntryReading *> *)values; I setup the following code to test which of these are actually implemented:
NSArray<NSString*>* selectors = @[ NSStringFromSelector(@selector(insertObject:inReadingsAtIndex:)), NSStringFromSelector(@selector(removeObjectFromReadingsAtIndex:)), NSStringFromSelector(@selector(insertReadings:atIndexes:)), NSStringFromSelector(@selector(removeReadingsAtIndexes:)), NSStringFromSelector(@selector(replaceObjectInReadingsAtIndex:withObject:)), NSStringFromSelector(@selector(replaceReadingsAtIndexes:withReadings:)), NSStringFromSelector(@selector(addReadingsObject:)), NSStringFromSelector(@selector(removeReadingsObject:)), NSStringFromSelector(@selector(addReadings:)), NSStringFromSelector(@selector(removeReadings:)) ];
for ( NSString* selector in selectors ) { if ( [entry respondsToSelector:NSSelectorFromString(selector)] ) NSLog(@"%@ exists.", selector); else NSLog(@"%@ does not exist.", selector); }
The results were:
insertObject:inReadingsAtIndex: exists. removeObjectFromReadingsAtIndex: exists. insertReadings:atIndexes: does not exist. removeReadingsAtIndexes: exists. replaceObjectInReadingsAtIndex:withObject: exists. replaceReadingsAtIndexes:withReadings: does not exist. addReadingsObject: exists. removeReadingsObject: exists. addReadings: exists. removeReadings: exists. So it looks like insertReadings:atIndexes: and replaceReadingsAtIndexes:withReadings: were not actually generated by Core Data.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/CFKevinRef/KCOrderedAccessorFix/issues/16?email_source=notifications&email_token=AAUGO2YBBG5CPGLL5WAUCR3QLS67NA5CNFSM4EKBKXCKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7VWEWY#issuecomment-535519835, or mute the thread https://github.com/notifications/unsubscribe-auth/AAUGO25JIVYLFJMOK3DO7DLQLS67NANCNFSM4EKBKXCA.
I just filed a radar, FB7330607. I also uploaded a simple test project illustrating the behavior here: https://github.com/clindsay/TestCoreDataOrderedRelationships
So if anyone finds this thread in the future and wants to check if they can finally drop KCOrderedAccessorFix
, running that project and checking the output is a good start.
Great work. By the way, do you have any idea what could happen if we do apply KCOrderedAccessorFix on OS versions with partial implementations? Could the implementations collide somehow? Who takes precedence?
Sent from my iPhone
On 27 Sep 2019, at 21:43, Chris Vasselli [email protected] wrote:
I just filed a radar, FB7330607. I also uploaded a simple test project illustrating the behavior here: https://github.com/clindsay/TestCoreDataOrderedRelationships
So if anyone finds this thread in the future and wants to check if they can finally drop KCOrderedAccessorFix, running that project and checking the output is a good start.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
I've been using it for years without issue, long after some of the methods seem to have been fixed. Glancing through the code, it looks like the KCOrderedAccessorFix
takes precedence to me:
https://github.com/CFKevinRef/KCOrderedAccessorFix/blob/master/NSManagedObjectModel%2BKCOrderedAccessorFix.m#L127
@Motti-Shneor it looks like this has finally been resolved in iOS 14. I can confirm that all of the accessors are implemented. I think we can finally retire this project for good. 🎉