Getting EXC_BAD_ACCESS when using dispatch_async with master data

I have images in coredata that I am trying to load lazily to represent a table. Each cell uses an observer for the associated main data object to update the image when it becomes available. The corresponding code in the object is as follows:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // The heavy lifting seems to be during firing of the fault and accessing data,
  // so i'm trying to do that in the background thread.
  UIImage *i = [UIImage imageWithData:self.imageEntity.data];
  // I now need to notify observers that the image is ready on the main thread
  dispatch_async(dispatch_get_main_queue(), ^{
    [self willChangeValueForKey:@"image"];
    image = i;
    [self didChangeValueForKey:@"image"];
  });
});

The project uses ARC, I don't get any compilation errors or warnings, and when I run it as works, until I scroll fast, and then get EXC_BAD_ACCESS in line when I declare i.

What am I missing here?

+5
source share
3 answers

-, CoreData . persistentStoreCoordinator, ObjectContexts. , :

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  @autoreleasepool {
    // Create a new context
    NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init];
    // Use an existing coordinator
    NSPersistentStoreCoordinator *coordinator = [[DataSource sharedDataSource] persistentStoreCoordinator];
    [backgroundContext setPersistentStoreCoordinator:coordinator];
    // Getting objectID does not fire the fault, so we grab it but actually fetch the object
    // on a background context to be thread safe.
    Image *imageEntity = (Image*)[backgroundContext objectWithID:self.imageEntity.objectID];
    image = [UIImage imageWithData:imageEntity.data];
    // Notify observers that the image is ready on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
      [self willChangeValueForKey:@"image"];
      [self didChangeValueForKey:@"image"];
    });
  }
});
+7

Dizy, , Image, :

UIImage *i = [UIImage imageWithData:self.imageEntity.data];

. dispatch_async , , , , , .

+1

CoreData is not thread safe, you must manage contexts to avoid crashes. If you plan to actively use many concurrent processes to update data in Core Data, I would suggest you take a look at MagicalRecord , an amazing sample inspired by Active Record of Rails that handles all of these aspects in a truly smart way.

0
source

All Articles