Jeef
Jeef

Reputation: 27265

CoreData query returns zero rests on subObjects initially - but after quitting all the data exists

I'm using CoreData and I have an entity called a FlightRecording contained inside of this entity is a set of messages AhrsMesages. I'm having strange behavior where I make a recording and then once I save the recording I load a table of past recordings which should show the number of messages per-recording. What is happening, however, is that it shows 0 messages. If I quit the application and restart-it and go into my recording list menu again it will correctly show the correct number of sub-entites.

I use the following code in ViewDidLoad of my PreviousFlightVC.m to load my flights:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"FlightRecording"];

NSSortDescriptor *originSort =
        [[NSSortDescriptor alloc] initWithKey:@"originAirport" ascending:YES];

NSSortDescriptor *destinationSort =
        [[NSSortDescriptor alloc] initWithKey:@"destinationAirport" ascending:YES];

NSSortDescriptor *dateSort =
        [[NSSortDescriptor alloc] initWithKey:@"recordingStart" ascending:YES];


fetchRequest.sortDescriptors = @[originSort, destinationSort, dateSort];
[fetchRequest setIncludesSubentities:YES];

self.frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];

self.frc.delegate = self;
NSError *fetchingError = nil;
if ([self.frc performFetch:&fetchingError]) {
    NSLog(@"Success Fetch");
} else {
    NSLog(@"Fetch Error");
}

For each cell I'm generating the Count as such:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

RecordingRowCell *cell = nil;

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {

    /* - IPAD Version */
    cell = [tableView dequeueReusableCellWithIdentifier:@"RecordingRowCell"];
} else {

    /* Iphone table Cells */
    cell = [tableView dequeueReusableCellWithIdentifier:@"iphoneFlightCell"];
}

FlightRecording *rec = [[[self frc] fetchedObjects] objectAtIndex:[indexPath row]];

// Count the records
int recordCount = [rec.ahrsMessages count];
NSLog(@"%d", recordCount);

// ...

Does anybody have any ideas why I might be seeing this behavior? Could I some how have left the "data" open for writing? Any suggestions would be great. Its a minor annoyance but I still can't exactly figure out why it is happening.

Here is my initial table (before quitting) - notice msgCount = 0 Before Case

After i quit the app and restart here is my table - notice msgCount = 6 After Case

Upvotes: 1

Views: 49

Answers (1)

Dan Shelly
Dan Shelly

Reputation: 6011

NSFetchedResultsController does not track changes in related objects to the ones it is fetching (in relationships).

In your case, an addition to the ahrsMessages set will not be reflected in the currently fetched objects.

In any case, your count fetching in cellForRow... is very expensive performance wise.
It will be better to store the count in the FlightRecording object itself.
each time you ask for the count for an object it need to resolve the to-many relationship (a trip to the store).

Each time you add a message to a recording, increase the count of recordings in the related recording object (which will be faulted-in anyway by CoreData).
This will also cause your FRC to hear of the change and update the view.

Upvotes: 1

Related Questions