Core Data: Error when deleting/adding objects

Sometimes my app crashes when I want to update my Core Data file by downloading and parsing a json file. I get the following error:

CoreData: error: Serious application error. Exception was caught
during Core Data change processing. This is usually a bug within an
observer of NSManagedObjectContextObjectsDidChangeNotification.
-[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)

  • Empty while loop hangs in iPhone release build
  • Swift Covariant Generics
  • Does Apple now require all iPad apps to be retina-screen ready?
  • UITableView - cellForRowAtIndexPath Is Not Being Called
  • XCode - undefined symbols for architecture armv7 arm64
  • Detect whether browser has keyboard/arrow keys in web page
  • Does it matter where I save the NSManagedObjectContext within an iteration if I change properties during iteration?

    here is my code:

    - (void) updateData
    {           
        dispatch_queue_t serialdQueue;
        serialdQueue = dispatch_queue_create("update", NULL);
        dispatch_async(serialdQueue, ^{
            [self method1];
        });
        dispatch_async(serialdQueue, ^{
            [self method2];
        });
        dispatch_async(serialdQueue, ^{
            [self method3];
        });
        dispatch_async(serialdQueue, ^{
            [self method4];
        });
        dispatch_async(serialdQueue, ^{
            [self method5];
        });
    
    }
    
    -(void)method1
    {        
        //DOWNLOAD JSON FILE
    }
    
    -(void)method2 //here i add objects to the core data file
    {        
        @try {
    
            for (NSDictionary *jsonActivity in [json objectForKey:@"Activities"]) {  //ITERATE THROUGH JSON ACTIVITY ARRAY
    
                NSFetchRequest *request = [[NSFetchRequest alloc] init];
    
                NSEntityDescription *entity = [NSEntityDescription entityForName:@"Activity" inManagedObjectContext:self.managedObjectContext];
                [request setEntity:entity];
    
                NSPredicate *searchFilter = [NSPredicate predicateWithFormat:@"title == %@", [jsonActivity objectForKey:@"title"]]; // CHECK IF OBJECT FROM JSON FILE ALREADY EXISTS...
                [request setPredicate:searchFilter];
                NSError *error = nil;
    
                NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error];
                if (error) {
                    NSLog(@"Error %@", error);
                    abort();
                }
    
                if ([results count] == 0) { // ADD NEW ACTIVITY IF OLD LIST DOESNT CONTAIN IT
    
                    Activity *activity = [NSEntityDescription insertNewObjectForEntityForName:@"Activity" inManagedObjectContext:self.managedObjectContext];
    
                    activity.title = [jsonActivity objectForKey:@"title"];
    
                    activity.remove = [NSNumber numberWithBool:NO]; // REMOVE FLAG = NO BECAUSE NEW OBJECTS AREN'T REMOVED
    
                } else  {
    
                    Activity *activity = (Activity*) [results objectAtIndex:0];
                    activity.remove = [NSNumber numberWithBool:NO]; // IF OBJECT ALREADY EXISTS IT SHOULD BE OBTAINED
                }
    
                AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
                [appDelegate saveContext]; // SAVE MO CONTEXT
            }
    
        }   @catch (NSException *exception) {
    
            NSLog(@"Exception: %@", exception);
        }
    }
    
    -(void)method3 // DELETE OLD OBJECTS 
    {   
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Activity" inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entityDescription];
    
        NSPredicate *searchFilter = [NSPredicate predicateWithFormat:@"remove == %@", [NSNumber numberWithBool:YES]];
        [fetchRequest setPredicate:searchFilter];
    
        NSArray *objectsToDelete = [[NSArray alloc] init];
    
        NSError *error = nil;
        objectsToDelete = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
        if (error) {
            NSLog(@"Error %@", error);
            abort();
        }
    
        for (Activity *activity in objectsToDelete) { // DELETE OBJECTS WITH THE PROPERTY REMOVE = YES
    
            [self.managedObjectContext deleteObject:activity]; // DELETE ACTIVITY
        }
    
        AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        [appDelegate saveContext]; // SAVE MO CONTEXT
    }
    
    -(void)method4 // CHANGE THE REMOVE PROPERTY TO YES OF ALL OBJECTS
    {        
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Activity" inManagedObjectContext:self.managedObjectContext];
        [fetchRequest setEntity:entityDescription];
    
        NSArray *objects = [[NSArray alloc] init];
    
        NSError *error = nil;
        objects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
        if (error) {
            NSLog(@"Error %@", error);
            abort();
        }
    
        for (Activity *activity in objects) {
    
            activity.remove = [NSNumber numberWithBool:YES];
        }
    
        AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
        [appDelegate saveContext]; // SAVE MO CONTEXT
    
        NSLog(@"End Update");
    }
    
    -(void)method5 //UPDATE UI
    {
        //UI UPDATES
    }
    

    Solutions Collect From Internet About “Core Data: Error when deleting/adding objects”

    You shouldn’t be accessing your managed object context on serialQueue. Take a look at the Concurrency section of the NSManagedObjectContext documentation.

    If in your code your context is using NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType concurrency type, you can use one of the block-based methods to ensure you’re on the right queue:

    //asyncrhonous
    [self.managedObjectContext performBlock:^{
        //do stuff with the context
    }];
    
    //syncrhonous
    [self.managedObjectContext performBlockAndWait:^{
        //do stuff with the context
    }];