1

I have a problem when trying to change the persistent store at runtime. The way I'm trying to do this is by doing a reinit of the whole core data stack:

- (void)initializeCoreDataForStore:(NSUrl *)storeURL withCompletionBlock:(CoreDataRWCompletionBlock)completionBlock
{
    //this code is needed to reset core data stack before re-creating the new one 
    [_managedObjectContextBackgroundQueue reset];
    _managedObjectContextBackgroundQueue = nil;
    [_managedObjectContextMainQueue reset];
    _managedObjectContextMainQueue = nil;
    _managedObjectModel = nil;
    _persistentStoreCoordinator = nil;
    _persitentStore = nil;
    
    //---------------end reset core data stack ---------------------
    
    //model
    self.managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    
    self.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];

    //main context
    self.managedObjectContextMainQueue = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [self.managedObjectContextMainQueue setPersistentStoreCoordinator:self.persistentStoreCoordinator];
    
    //background context
    self.managedObjectContextBackgroundQueue = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [self.managedObjectContextBackgroundQueue performBlockAndWait:^{
        [self.managedObjectContextBackgroundQueue setPersistentStoreCoordinator:self.persistentStoreCoordinator];
    }];
    
    dispatch_queue_t queue = NULL;
    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        NSError *error = nil;
        self.persitentStore  = [self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]; 
        dispatch_sync(dispatch_get_main_queue(), ^{
            if (completionBlock) {
                completionBlock([error localizedDescription], nil);
            }
        });
    });
}

All the work on the background context is made with performBlock or performBlockAndWait. The problem is that, event if I reset and reinit the stack, if there are pending "operations" on the old background context, those operations are not canceled, and they continue to execute, more than this, they are trying to execute using the newly instantiated background context, which has another persistent store. Is there a way to cancel all operations from the private queue associated with the background context(the way nsoperations can be canceled on an operation queue)?

twin
  • 11
  • 1
  • http://stackoverflow.com/questions/1550658/dispatch-queues-how-to-tell-if-theyre-running-and-how-to-stop-them?rq=1 – user523234 Mar 06 '14 at 11:59
  • Thanks for the link, but I think it does not solve my case. First of all I don't have access to the private queue that is associated with the backgroundContext. If you suggest I should add an empty block with performBlock on the background context that represents the last one on the queue(allTasksDone), there may be other threads that can add blocks to the queue my "last one". – twin Mar 06 '14 at 13:00

0 Answers0