Skip to content

BrianSemiglia/BSThreadSafeCoreDataOperationQueue

Repository files navigation

BSThreadSafeCoreDataOperationQueue

A custom NSOperationQueue for concurrent, thread-safe operations with Core Data. iOS 4+


Operations are submitted to a static, shared, concurrent operations queue. Operations are not guaranteed to run in any particular order. Operations do not block the thread they were submitted from. A managed object context is created for each operation. The managed object context provided to the block can be access from any thread/queue but not concurrently. The confinement of the MOC to the block makes it easy to manage accessing the context from different threads/queues.

 // 1. Allowed: SYNC operations submitted to other threads/queues.
 [[BSThreadSafeContextController sharedInstance] addOperationWithContext:^(NSManagedObjectContext *context)
 {
      // Operation will block until completed.
      // Safe to access context after operation.

      dispatch_sync(dispatch_get_main_queue(), ^{
          // Access context on main queue.
      });

      [context message];
 }];

 // 2. Disallowed: ASYNC operations submitted to other threads/queues BEFORE any additional messages to the context.
 [[BSThreadSafeContextController sharedInstance] addOperationWithContext:^(NSManagedObjectContext *context)
 {
      // Operation will not block.
      // Because of the message to context below the block, a situation is created 
      // where the context might be accessed by two different threads/queues at the same time.

      dispatch_async(dispatch_get_main_queue(), ^{
          // Access context on main queue.
      });

      [context message];
 }];

 // 3. Allowed: ASYNC operations submitted to other threads/queues AFTER any additional messages to the context.
 [[BSThreadSafeContextController sharedInstance] addOperationWithContext:^(NSManagedObjectContext *context)
 {
      // Operation will not block but is last to message context thus
      // guaranteeing the context will not be accessed by any other threads/queues.
      
      dispatch_async(dispatch_get_main_queue(), ^{
          // Access context on main queue.
      });

      // No additional messages to the context.
 }];

.

- (void)sampleSave
{
    [[BSThreadSafeContextController sharedInstance] addOperationWithContext:^(NSManagedObjectContext *context)
    {
        NSEntityDescription *entity = [NSEntityDescription insertNewObjectForEntityForName:@"Entity"
                                                                    inManagedObjectContext:context];

        NSError *error = nil;
        [context save:&error];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Saved.");
        });
    }];
}

- (void)sampleFetch
{
    [[BSThreadSafeContextController sharedInstance] addOperationWithContext:^(NSManagedObjectContext *context)
    {
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:context];        
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
        
        request.entity = entity;
        request.sortDescriptors = @[sortDescriptor];
        
        NSError *error = nil;
        NSArray *fetchedObjects = [context executeFetchRequest:request
                                                         error:&error];

        dispatch_async(dispatch_get_main_queue(), ^
        {
            NSLog(@"Fetched %i items.", fetchedObjects.count);
            
            // Access the objects safely from another thread.
            NSLog(@"Sample: %@", fetchedObjects[0]);
        });
    }];
}

About

A custom NSOperationQueue for concurrent, thread-safe operations with Core Data. iOS 4+

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published