Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreData + iCloud + Cascade Delete - how to handle?

CoreData Entity "A" has a one-to-many relationship to a collection of CoreData Entries "B", using a Cascade delete rule.

In an iCloud environment, while device 1 shows a detail view of one of the "B" entries, device 2 deletes the "A" entry.

When the NSPersistentStoreDidImportUbiquitousContentChangesNotification notification is received in device 1, its App Delegate calls mergeChangesFromContextDidSaveNotification and then broadcasts an internal notification which is captured by the view controller showing the details of entry "B" (the code uses performBlock where it should).

However, although entry "A" is indeed nullified when the detail view controller receives the internal notification, entry "B" still exists as a valid CoreData object. It seems that the Cascade rule hasn't completed its operation yet. Therefore the view controller in device 1 isn't aware of the delete, which may lead to unexpected results.

mergeChangesFromContextDidSaveNotification appears to return prematurely, when the base data has been merged but the Cascade rule hasn't completed yet.

I tried to refresh entry "B" when the notification arrives while temporarily setting the stalenessInterval of the managed object context to zero so a cached object won't be used, but I still get a valid entry "B" from the store.

Checking for a null entry "A" at this point is not an option, because the situation is somewhat more complex than what I described here and a null entry "A" can be valid in some cases.

I tried to introduce a delay after merging the changes and before sending the internal notification to the view controllers. I found out that a 2-second delay doesn't help, but a 10-second delay works.

But I don't want to rely on this delay. This is a test environment without much data, and I don't know what will happen in a production environment. Relying on an experimental delay doesn't seem the right thing to do.

Is there a right thing? Or am I doing something wrong to begin with?

like image 427
Amiram Stark Avatar asked May 11 '12 20:05

Amiram Stark


People also ask

Should I use delete cascade?

ON DELETE CASCADE is fine, but only when the dependent rows are really a logical extension of the row being deleted. For example, it's OK for DELETE ORDERS to delete the associated ORDER_LINES because clearly you want to delete this order, which consists of a header and some lines.


1 Answers

From experience, listening to notifications other than NSManagedObjectContextDidSaveNotification is a big mess and can lead to relying on properties not yet updated. The detail view controller should listen to NSManagedObjectContextDidSaveNotification notifications, which are thrown after cascade is applied. You can then check by several means if the current object is valid or not (you can check to see if the current object's managed object context is nil or you can perform a fetch and see if the object exists in the store).

like image 180
Léo Natan Avatar answered Oct 30 '22 07:10

Léo Natan