3

Here's what I'm trying to do:

  1. I use NSFetchedResultsController to perform a fetch and track changes using its delegate
  2. I download some data and depending on some condition I sometimes delete all local data stored by CoreData by removing the NSPersistentStore and recreating a new one.
  3. I create managed objects based on the data and save them
  4. NSFetchedResultsController should now inform me that I have some changes

What I get instead is this crash when trying to save the data:

CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. Object's persistent store is not reachable from this NSManagedObjectContext's coordinator with userInfo (null)

I'm always using a single NSManagedObjectContext and I always read & save on the main thread.

It seems that switching the NSPersistenStore somehow messes up the fetched results controller. Is this expected behavior or am I doing something wrong?

Mihai Damian
  • 11,193
  • 11
  • 59
  • 81

3 Answers3

3

I would not recommend this approach. I would create a new MOC with your new persistent store and let go of the old MOC.

I assume at some point you call -[ManagedObjectContext reset]? Before you do that, you have to let go of all managed objects that come from that context. They all become invalid (which is likely the cause of your crash).

You should also take a look at How to force coredata to rebuild sqlite database model?.

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Tried with reset as well; still no change. I am already removing/adding the persistent store with `removePersistentStore:error` `addPersistentStoreWithType:configuration:URL:options:error`. If I need to recreate the MOC then I presume I have to recreate the NSFetchedResultsController as well; I am trying to avoid that to reduce coupling in the app – Mihai Damian Feb 10 '12 at 14:54
  • Yes, I believe removing the NSFetchedResultsController would be core to the solution. I can't think of a way to rip all the data out (without change notices via calls to `deleteObject:`) while keeping around objects that reference that data. – Rob Napier Feb 10 '12 at 16:10
  • 1
    Well in theory NSFetchedResultsController could be notified by the MOC once it's underlying storage vanishes that all the objects in its result set were deleted. No idea how this is handled internally though. – Mihai Damian Feb 10 '12 at 16:33
  • @RobNapier, I need your help, I am facing a issue while resetting all my data from coreData. here is my question http://stackoverflow.com/questions/19358095/core-data-reset – Ranjit Oct 15 '13 at 13:44
2

I had the same crash. Following Rob's suggestion, I additionally posted an NSNotification each time I called removePersistentStore: - and all my ViewControllers that have an NSFetchedResultController now automatically nullify their local NSFetchedResultsController when that happens.

i.e.:

1 - LISTEN TO NOTIFICATION:

-(id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
    // Custom initialization
    [[NSNotificationCenter defaultCenter] addObserverForName:kNotificationDestroyAllNSFetchedResultsControllers object:nil queue:nil usingBlock:^(NSNotification *note) {
        NSLog(@"[%@] must destroy my nsfetchedresultscontroller", [self class]);
        [__fetchedResultsController release];
        __fetchedResultsController = nil;
        }];
    }
    return self;
}

2 - POST NOTIFICATION

for( NSPersistentStore* store in [self.persistentStoreCoordinator persistentStores] )
{
    NSError *error;
    NSURL *storeURL = store.URL;
    [self.persistentStoreCoordinator removePersistentStore:store error:&error];
    [[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];

    /** ... side effect: all NSFetchedResultsController's will now explode  */
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationDestroyAllNSFetchedResultsControllers object:self];
}
Adam
  • 32,900
  • 16
  • 126
  • 153
0

The NSFetchedResultsController monitors changes to objects in its associated managed object context thus it might be monitoring changes to objects in an obsolete managed object context.

This issue got fixed when I recreated the NSFetchedResultsController after resetting the NSPersistentStore

faris.halteh
  • 71
  • 1
  • 1