Closed pierrephi closed 10 years ago
Thanks for reporting this. The reason why this happens is that I dynamically subclass both IMIRegister and IMIHistoryRegister, and the subclassed IMIHistoryRegister doesn't inherit from the subclassed IMIRegister...
I believe the solution to this is to not do dynamic subclassing at all, but instead to use method-swizzling. This is a much more straight-forward approach and should hopefully vastly simplify the code, but will take a bit of work.
Turns out my idea won't work. I've pushed a partial solution that should solve your problem. It only works when CoreData entities inherit from abstract entities. You'll still get similar problems if you have concrete entities inheriting from concrete entities. I'll think more about how to solve that, but let me know if my fix solves your problem.
That should fix the problem properly. Let me know if you have any issues.
Thanks Graham, Good trick, unfortunately, that doesn't fix it for me because my base class is only abstract in principle since I am migrating from an older version of my data model and the class at the root of the hierarchy cannot be actually abstract, When it migrates the initial state of my store is only composed of abstract entities until I programmatically instantiate the derived classes. In my implementation I also have several levels of hierarchy and some levels are not abstract. I trust this will help others though
So the last version doesn't work? Commit 4995dbf was supposed to fix the problem for non-abstract entities too. If there's still a problem, let me know and I'll take another look.
I did give it a spin and got the same error, let me come up with a test case so you can reproduce first hand. The error has slightly changed, the desired type is still the modified type but the given type is now correct
2014-03-21 11:05:17.727 Kotoba![47139:60b] *\ Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-one relationship: property = "registre"; desired type = IMIRegister_GDCoreDataConcurrencyDebugging; given type = IMIHistoryRegister; value = <IMIHistoryRegister: 0xc1152f0> (entity: IMIHistoryRegister; id: 0xc1154f0 x-coredata://09A5AB63-7D2B-4DF8-88E4-5A4CBDB114F8/IMIHistoryRegister/p6 ; data: {
@pierrephi: This should now fix it. I've tested it myself. Please give it a try, if it works I'll push a new version.
Graham, superb! I have tested this and it seems to work perfectly Thank you!
Great!
I have been using this utility for a while now and recently I upgraded my data model to something a bit more complex with object inheritance
Lets say I have 2 base classes
IMIRegister and IMIRegisterItem both are abstract and IMIRegister references a collection of IMIRegisterItems (to many relationship "items") IMIRegisterItem has a reverse relationship "registre" and at some point I assign
IMIRegister aRegister; IMIRegisterItem aRegisterItem;
aRegisterItem.register = aRegister
in my code both aRegisterItem and aRegister are of the base class type but at runtime they are of a concrete type, it seems that class name fiddling performed by GDCoreDataConcurrencyDebugging prevents the objective C CoreData run-time to correctly recognise the concrete type instance as a valid pointer to the abstract type
If this is not clear I will try and make a small example to reproduce