drewmccormack / ensembles

A synchronization framework for Core Data.
MIT License
1.63k stars 131 forks source link

Is this possible with Ensembles? #240

Closed debriennefrancoisjean closed 8 years ago

debriennefrancoisjean commented 8 years ago

My CoreData model classes run code when relationships get updated (addChildObjects: ; removeChildObjects). These are the standard setters and getters for relationships.

Let's imagine we have ObjectA -1..n> ObjectB -1..1> ObjectC

in ObjectA.addObjectBObjects I call a method on ObjectA which expects any ObjectB that have been added to also have their relationship to ObjectC set.

In my experience with Ensembles so far (only been trying it out for a day), the ObjectB.ObjectC relationship is unexpectedly nil at a certain point in time which causes my code in ObjectA to fail (it expects ObjectC to be related to ObjectB).

Am I doing something wrong or is this not possible with Ensembles?

I'm currently testing with v1.x but would migrate to v2 if this particular situation is eased.

drewmccormack commented 8 years ago

Ensembles uses standard setValue:forKey:. It should not end up calling the custom setter, I don't think. (Note also that core data sometimes will not set the inverse relationship until processPendingChanges is called.)

Does your model use parent entities, with relationships on the parents? I think there was some corner cases in v1 for that that were fixed in v2.

Kind regards, Drew

On 30 Jul 2016, at 05:20, François-jean de Brienne notifications@github.com wrote:

My CoreData model classes run code when relationships get updated (addChildObjects: ; moreveChildObjects). These are the standard setters and getters for relationships.

Let's imagine we have ObjectA -1..n> ObjectB -1..1> ObjectC

in ObjectA.addObjectBObjects I call a method on ObjectA which expects any ObjectB that have been added to also have their relationship to ObjectC set.

In my experience with Ensembles so far (only been trying it out for a day), ObjectC is nil at a certain point in time which causes my code in ObjectA to fail (it expects ObjectC to be related to ObjectB).

Am I doing something wrong or is this not possible with Ensembles?

I'm currently testing with v1.x but would migrate to v2 if this particular situation is eased.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

debriennefrancoisjean commented 8 years ago

After digging into this a little more, I'd like to share my findings with others who may have a similar problem.

I was assuming that my object graph was completely informed at certain points of my app, since my UI informs managed objects in a consistent manner. This is a programming mistake on my part; a core data object graph can only be considered valid and complete at the moment it is saved (if it doesn't contain errors). Anytime before that and you are relying on your own code to populate objects in a consistent fashion.

Obviously, Ensembles does not know of my business logic and was informing objects of their relationships "early", when the objects themselves hadn't setup all their other children relationships and values.

The moral of the story is that, only consider the core data graph as complete when the context is about to save, not while objects are being updated.

I moved some code around from the relationship setters to the willSave NSManagedObject method. This has some risks of running an infinite loop of saves but if you follow some simple guidelines (check if the object is being deleted, check if relevant values have changed using the changedValues property, don't redo the calculations more than once), it is a much safer proposition and it seems to work well with Ensembles now.