Search code examples
iosmultithreadingcore-datansmanagedobjectcontextnsfetchrequest

Illegal access to Core Data context: what thread is the owner of the context provided in AppDelegate?


I have a class with a method like this:

- (void)getEntities
{
   AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
   NSManagedObjectContext *mainContext = appDelegate.managedObjectContext;

   NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MyEntity"];
   NSArray *entities = [mainContext executeFetchRequest:fetchRequest error:nil];

   for (NSManagedObject *item in entities) {
      NSLog(@"Name: %@", ((MyEntity *)item).name);
   }
}

I have enabled the com.apple.CoreData.ConcurrencyDebug 1 and when I call this method (in main thread) I get the error:

CoreData: error: The current thread is not the recognized owner of this NSManagedObjectContext(0x16d40160). Illegal access during executeFetchRequest:error:

However, if I do:

- (void)getEntities
{
   NSManagedObjectContext *privateContext = [CoreDataStack getPrivateContext];

   if (privateContext != nil) {
       [privateContext performBlock: ^{
           NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"MyEntity"];
          NSArray *entities = [privateContext executeFetchRequest:fetchRequest error:nil];

          for (NSManagedObject *item in entities) {
             NSLog(@"Name: %@", ((MyEntity *)item).name);
          }
      }];
   }
}

And I call it also in main thread, it does not seem to cause such Core Data error... why? I've been always assuming that the NSManagedObjectContext provided by default in AppDelegate and I'm retrieving belongs to main thread... What I'm doing wrong or missing?

The entities I'm trying to fetch using the context from AppDelegate where previously saved from a context that was created in a private queue (similar to the one I create in my second code snippet). Could that be the cause of the error? Such private context was not a child of any other context, and I had no error when saving it.

I need to get the entities I have already stored by using a private context in the main thread, to keep them in an NSArray in the implementation of an UIViewController.

Thanks so much in advance.


Solution

  • It seems that the problem wasn't in the method but my initialization of the context in AppDelegate: before calling the method in the question, and in certain scenario I was retrieving the context the first time from a queue that wasn't the main thread, and that seemed to be causing the context to be initialized in that other queue.