CoreData/problems with "cross-entity observing" / Undo / Redo / Save
CoreData/problems with "cross-entity observing" / Undo / Redo / Save
- Subject: CoreData/problems with "cross-entity observing" / Undo / Redo / Save
- From: Grigory Entin <email@hidden>
- Date: Wed, 10 May 2006 23:16:13 +0400
Hello,
Could somebody point me to some sample CoreData code where properties
of some entities depend on the properties of other (related) entities
and that uses Undo/Redo (and that uses automatic / periodic MOC save)?
The problem is that I'm trying to use KVO to track "external"
properties (i.e. properties entities referenced by "relationships" of
the source entity) by embedding add/removeObserver: calls into the
observing entity code (particularly, I tried
-set<Foo>:/-awakeFromFetch for that) but I facing a number of problems
(writing from memory, so can be wrong in some detail, but I hope you
get the idea), please note that it's related to periodic MOC save too:
1. -set<Foo>: *can not* be used to stop observing as it doesn't called
on object removal, neither can be -didTurnIntoFault as it's called
too late when all the properties (one of which is the observed
relationship) are nil. I ended up with overriding
-setPrimitiveValue:forKey: to catch the nil setting for the key, it
sounds like a hack and probably results in some other problems.
2. For to-many *bidirectional* relationship, while performing
Undo/Redo sometimes I get the following case (probably side effect
of the above hack, but I'm not sure): even if I remove the object
(or set it to nil) at one side, it doesn't get removed / set to nil
on the "other side".
I frankly don't know whether relationship setter method /
-awakeFromFetch are the correct places to put the code for observer
(de)registration, so probably that the "main" problem. Any
suggestions?
Non-related, but another strange phenomenon that I observed with *no
custom entity code* / autogenerated "Core Data Application" type
project, while trying to "isolate the problems" (can 100% reproduce it
with "just" NSManagedObjects).. Would very grateful to anyone who
could help to understand it, as the results are very close to the same
as for "2" above):
>>
If you set propagatesDeletesAtEndOfEvent to NO for a MOC, create two
objects for two entities:
- one is "owner" with to-many itmes relationship and cascading delete rule
- another is "item" with (reverse) 1-1 "owner" relationship with nullify
delete rule),
deleting the "owner" object and saving afterwards results in expected
results ("item" object is deleted), but if you make
-processPendingChanges call between the deletion and save, the "item"
object remains untouched, moreover it "owner" relationship remains set
to the original owner item (that no longer exists) - same as for
mentioned above.. Probably I don't understand "processPendingChanges"
usage, but I would very like to know why it does result in these
things they are the same side effects as I have in my custom
application..
Quoting the relevant code, for the "curious"..
The model contains two entities (delete rules are in round brakets):
---------------------- -----------------
ARCascadingOwnerItem ARCascadingOwner
owner (nullify) <<-> items (cascade)
---------------------- -----------------
Below is -managedObjectContext of autogenerated XXX_AppDelegate, the
only change is -setPropagatesDeletesAtEndOfEvent: call.
>>>
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self
persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:
coordinator];
// here is the change:
[managedObjectContext setPropagatesDeletesAtEndOfEvent: NO];
}
return managedObjectContext;
}
>>>
And this is the test method, triggered by a button press in the
(automatically) generated window; removing #if 1-ed fragment
(-pendingChanges call) results in expected behaviour ("fault"
displayed for the object):
>>>
- (void) nscascadingDeleteT
{
NSError *error;
NSManagedObjectContext *moc = [self managedObjectContext];
NSManagedObject *owner =
[NSEntityDescription
insertNewObjectForEntityForName: @"ARCascadingOwner"
inManagedObjectContext: moc];
NSManagedObject *object =
[NSEntityDescription
insertNewObjectForEntityForName: @"ARCascadingOwnerItem"
inManagedObjectContext: moc];
[object setValue: owner forKey: @"owner"];
NSLog (@"[owner isDeleted]: %d", [owner isDeleted]);
NSLog (@"[object isDeleted]: %d", [object isDeleted]);
if (![moc save: &error]) {
NSLog (@"error: %@", error);
}
[moc deleteObject: owner];
NSLog (@"[owner isDeleted]: %d", [owner isDeleted]);
NSLog (@"[object isDeleted]: %d", [object isDeleted]);
NSLog (@"[object isFault]: %d", [object isFault]);
#if 1
[moc processPendingChanges];
#endif
if (![moc save: &error]) {
NSLog (@"error: %@", error);
}
NSLog (@"[owner isDeleted]: %d", [owner isDeleted]);
NSLog (@"[object isDeleted]: %d", [object isDeleted]);
NSLog (@"[object isFault]: %d", [object isFault]);
NSLog (@"%@", object);
}
>>>
Any comments / help are welcome..
Regards,
Grigory
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden