Reputation: 2381
Long question---thanks in advance for your time. After saving new managed objects, I am finding them added to a relationship on another object in my core data database---one for which my code calls no setter method and that has no inverse relationship. I have pored over the code and used logs to isolate the occurrence the best I can, but I'm encountering bizarre behavior I cannot explain (or fix).
More specifically:
I have an entity called PendingSyncTracker
. It simply has one relationship, objectsToSync
. I have not yet added any line in my code to call a setter method on this relationship. It is a to-many relationship. It points to BaseEntity
. For the "Inverse" option, I have selected "No Inverse Relationship."
When I load a particular table view, 3 objects are downloaded from a server and then parsed into managed objects and saved. By the time the table view begins loading cells, 2 of those 3 objects will mystifyingly be present in the objectsToSync
relationship.
I have used NSLog
all over my code to figure out exactly when these objects can first be found as members of the objectsToSync
set.
NSSet *objectsToSync = [[[SyncEngine sharedEngine] fetchClassNamed:@"PendingSyncTracker" withPredicates:nil][0] valueForKey:@"objectsPendingSync"];
NSLog(@"PendingSyncTracker objectsToSync set (%lu objects): %@", (unsigned long)[objectsToSync count], objectsToSync);
The answer to when they first appear in the set actually varies depending on where I do/don't place those 2 lines of code!
The objects are never found on the relationship before the managed object context is saved in the course of saving my 3 new core data objects.
If I don't use those 2 lines till I'm back in the Table View Controller that sent the new objects off to the Sync Engine to be stored locally (where the MOC is accessed and saved), then the log will there reveal that 2 objects have been added to the relationship.
If I use those 2 lines immediately after saving the MOC in the Sync Engine, then the logs will indicate (both there and back in the TVC) that only 1 object has been added to the relationship.
If I use those 2 lines immediately before and after saving the MOC (and back in the TVC), then all 3 logs will reveal that the relationship contains an empty set.
I also have those 2 lines at the beginning of cellForRowAtIndexPath
. Regardless of prior logs, that log will always indicate that 2 objects have been added to the relationship.
All 3 of the managed objects that are created in the Sync Engine are stored as entity types that are subEntities of BaseEntity
(to which the objectsToSync
relationship points). The 2 types that get added to the relationship are each defined to have a reciprocal relationship, but with a different object, not PendingSyncTracker
(although the different object is a subEntity of BaseEntity!).
So.. what explains these observations? How are these objects getting added to the relationship?
UPDATE:
- (NSArray*) fetchClassNamed:(NSString*)className withPredicates:(id)parameters;
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:className inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// set predicates
if (!(parameters == nil)) {
[fetchRequest setPredicate:parameters];
}
NSError *error;
NSArray *fetchedResults = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
return fetchedResults;
}
Upvotes: 0
Views: 167
Reputation: 46718
First, what does [[[SyncEngine sharedEngine] fetchClassNamed...
do? Just a guess but it is doing something with KVC to set the relationship for you.
Also, you should always, always, always have an inverse relationship. Even if you never use it, Core Data does. Not having an inverse can lead to lots of issues, including but not limited to performance problems and potentially data corruption.
Add an inverse relationship and update your question with what -fetchClassNamed...
does.
Upvotes: 1