Reputation: 25701
I have a method which creates a separate thread:
// Create thread
dispatch_queue_t uniqueQueue = dispatch_queue_create("Unique Email Queue", NULL);
// Run block on another thread called downloadQueue
dispatch_async(uniqueQueue, ^{
// Save to core data for redundancy
User *coreDataUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managedObjectContext];
coreDataUser.username = [emailStr lowercaseString];
coreDataUser.email = emailStr;
coreDataUser.name = nameStr;
NSError *error;
if (![self.managedObjectContext save:&error])
{
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}
The app always crashes on this line:
User *coreDataUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managedObjectContext];
I am using this tutorial as a reference: http://www.codigator.com/tutorials/ios-core-data-tutorial-with-example/
What am I missing?
Upvotes: 1
Views: 1060
Reputation: 1315
NSManagedObjectContext
is not threadsafe, try to create new moc in side of the async block.
Try:
// Create thread
dispatch_queue_t uniqueQueue = dispatch_queue_create("Unique Email Queue", NULL);
// Run block on another thread called downloadQueue
dispatch_async(uniqueQueue, ^{
// Save to core data for redundancy
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:persistentStoreCoordinator];
User *coreDataUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:context];
coreDataUser.username = [emailStr lowercaseString];
coreDataUser.email = emailStr;
coreDataUser.name = nameStr;
NSError *error;
if (![context save:&error])
{
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}
The persistent store is in your AppDelegate
Upvotes: 4
Reputation: 13860
Remember - CoraData is not thread safe !!!!!
If you want separate thread for your managedObjectContext
you have to create one on this thread. To call proper context you have to run it with performBlock
block. In your case:
[self.managedObjectContext performBlock:^{
User *coreDataUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managedObjectContext];
coreDataUser.username = [emailStr lowercaseString];
coreDataUser.email = emailStr;
coreDataUser.name = nameStr;
NSError *error;
if (![self.managedObjectContext save:&error])
{
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}];
But remember, if you creating context on mainThread, your block is also executed on mainThread.
Upvotes: 3