Andreas
Andreas

Reputation: 2725

What's the point of self.managedObjectContext == nil in NSManagedObject prepareForDeletion?

I have a Reminder entity that needs to update its date property whenever a certain entity B is deleted. I've spent some days coding thinking I could do some useful things in my managed object subclass on deletion time. I tried

- (void)willSave
{
if (self.isDeleted) 
    // use self.managedObjectContext
}

The context was nil. Relationships were also torn down there. Fair enough.

So... I started writing cumbersome code for prepareForDeletion to circumvent the fact that the object hadn't been deleted yet, but then Core Data throws self.managedObjectContext == nil in my face. The documentation says that this is where I do stuff "before relationships are torn down". So what is the point in self.managedObjectContext == nil if self.relationshipA.managedObjectContext is accessible (as the docs suggest)? And more importantly, why does my not yet deleted object not have its context?

I read a comment here regarding that problem

its not 'fault' as much as it is a 'disown', the context has disowned your object (he was deleted and save was committed to the database) and so your object was disowned. don't save in methods that are changing and object as the save should probably be committed/saved after the operation anyway. – Dan Shelly May 21 at 19:05

My code was:

[moc deleteObject:obj]
[moc save:NULL]

When I removed the save operation my self.managedObjectContext existed in prepareForDeletion. That is, until auto-save, when it was nil again. Probably because the parent context also deleted it, followed by a save by the UIManagedDocument.

I'm starting to think that my only options are to make a custom delete method (that works until Core Data cascades a deletion, in which case it won't be called), or make a new class that listens to NSManagedObjectContextDidSaveNotification.

Update:

My core data model

The user wants to keep in touch with a person, and wants to be reminded after a certain interval (stored in ContactWish) if no contact has been made. What I'm trying to accomplish is that when the latest ContactOccasion for a certain person is deleted, the corresponding occasion->person->wish->reminder gets updated (using the interval).

Since this is a learning experience for me I wanted to find out the right way (one that works with cascade deletion etc.) and not just call for an update manually from every place in my code where I do [MOContext deleteObject:occasion]. Suggestions are welcome.

(the reminder entity has also been prepared for more manual use)

Upvotes: 2

Views: 843

Answers (1)

Mundi
Mundi

Reputation: 80265

Would it not be much more logical to have the Reminder entity manage its date property? It could "listen" (maybe via changedValues:) to its relationship entities being deleted and perform the update.

This seems more consistent, as the B entity should not really be concerned with the logic of the Reminder entity updates.

Edit
Pursuant to the discussion below and based on my opinion that you cannot load up the database cascade delete model too much with update logic:

Rather than react to a deletion you can introduce an attribute that you set and listen to in order to do the changes.

I really do not see how relying on core data delete mechanisms is easier or more elegant than just writing your own "deleteOccasion" method that handles this logic.

Upvotes: 1

Related Questions