ruthless
ruthless

Reputation: 1140

Changed core data is not showing on tableview

I have been stuck on debugging this problem for hours and need some help. First, below is the function code that I am having a problem:

- (void)addAllHomeworkInstances:(Homework *)homework
{
    // Gets all the subjects that match
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Subject"];
    request.predicate = [NSPredicate predicateWithFormat:@"(name = %@) AND (teacher = %@)", self.subject.name, self.subject.teacher];

    // Finds matches from request
    NSError *error;
    NSArray *matches = [[homework managedObjectContext] executeFetchRequest:request error:&error];
    if (error || !matches) {
        NSLog(@"Error when trying to add homework for all subjects: %@", error);
    }
    else {
        [matches enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            // Adds the homework to each subject
            if ([obj isKindOfClass:[Subject class]]) {
                Subject *eachSubject = (Subject *)obj;

                // Makes sure subject is not the current one since
                if (![eachSubject isEqual:self.subject]) {
                    NSMutableSet *homeworkInSubject = [[NSMutableSet alloc] initWithSet:eachSubject.homework];
                    [homeworkInSubject addObject:homework];
                    eachSubject.homework = homeworkInSubject;
                }
            }
        }];
    }
}

Now the problem is occurring on the line eachSubject.homework = homeworkInSubject;. Basically, my view controller displays homework for a given class and this function gets called when we add a homework for the class.

If I comment out the line above, the added homework gets displayed on the current view controller as it has been added to the class. What the commented line is supposed to do is to update other subjects' (not the current one) homework set by adding the homework to it. When I uncomment the line out, the other subjects get updated in core data.

The problem is that even though the current subject's core data gets updated, the current view controller does not display the subject. I have tried to do a performFetch to update the data, reloadData for the tableview, and even reinitialized the fetchedResultsController but nothing worked.

I was thinking that changing core data was the cause of the problem, but I tested that by simply using the following code in the if condition, proving that it was not the case:

if (![eachSubject isEqual:self.subject]) {
    NSMutableSet *homeworkInSubject = [[NSMutableSet alloc] initWithSet:eachSubject.homework];
    eachSubject.homework = homeworkInSubject;
}

So right now, I am totally helpless. I tried so many things but none are giving me the right result.

EDIT:

This is my code that I used to display the tableview by initializing the fetchResultsController, but I am 99 percent sure that there is no problem with this, as commenting the problematic line above still works fine with this:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self initializeFetchResultsController];
}

// Initializes the NSFetchedResultsController to the following request
- (void)initializeFetchResultsController
{
    // Makes a request for the given entity
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Homework"];
    request.predicate = [NSPredicate predicateWithFormat:@"inClass = %@", self.subject];
    request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"dueDate"
                                                              ascending:NO],
                                [NSSortDescriptor sortDescriptorWithKey:@"title"
                                                              ascending:YES
                                                               selector:@selector(localizedStandardCompare:)]];
    // Creates a fetchedResultsController
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                        managedObjectContext:[self.subject managedObjectContext]
                                                                          sectionNameKeyPath:nil
                                                                                   cacheName:nil];
}

Upvotes: 0

Views: 55

Answers (1)

mitrenegade
mitrenegade

Reputation: 1844

When are you telling the tableview to reload the data? The order that the fetching, enumerating, and inserting isn't serial (you're using a block) so they're happening at various different timings. I assume you're doing something like:

[self addAllHomeWorkInstances:homework];
[self.tableView reloadData];

This probably won't work since you're not guaranteed to finish updating the Subject objects. One thing you can try is to reload data after a delay, to see if that is the issue. A better way would be to add a completion block so you have something like

[self addAllHomeworkInstances:homework completion: ^{
    [self.tableView reloadData];
}];

With the completion block being called each time inside the enumerateObjectsUsingBlock block.

Edit after we figured it out:

The issue seems to be the relationship between your objects. homework and subject must be a many to many relationship, and homework belonged to only one subject at the time of the question being posted. So when other subjects took over the homework, it was removed from the current subject.

Upvotes: 1

Related Questions