保存在不同的线程时,应用程序崩溃

时间:2013-11-22 08:47:37

标签: ios multithreading core-data nsmanagedobjectcontext

我有一个创建单独线程的方法:

// 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]);
        }            
    }

应用程序总是崩溃在这一行:

User *coreDataUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managedObjectContext];

我使用本教程作为参考:http://www.codigator.com/tutorials/ios-core-data-tutorial-with-example/

我错过了什么?

2 个答案:

答案 0 :(得分:4)

NSManagedObjectContext不是线程安全的,尝试在异步块的一侧创建新的moc。 尝试:

// 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]);
        }            
    }

持久性商店位于AppDelegate

答案 1 :(得分:3)

记住 - CoraData不是线程安全的!!!!!

如果你想要managedObjectContext的单独线程,你必须在这个线程上创建一个。要调用正确的上下文,您必须使用performBlock块运行它。在你的情况下:

[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]);
        }   
}];

但请记住,如果您在mainThread上创建上下文,您的块也会在mainThread上执行。