核心数据:插入对象崩溃在全局队列

我有一个非常简单的核心数据演示,其中只有一个button。

当我点击“运行”button时,应用程序在全局队列中运行的for循环中创build10,000个对象。

更新更多的细节:如果我把主循环for循环,它运行良好。

更新我的意图:我知道MOC不是线程安全的,但根据Apple文档 ,我们也可以使用串行队列来访问MOC,并且串行队列使用多个线程。

在这里我创build了核心数据堆栈:

#pragma mark - Core Data Stack - (NSManagedObjectContext *)managedObjectContext { if (nil != _managedObjectContext) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc] init]; if (self.persistentStoreCoordinator) { [_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator]; } return _managedObjectContext; } - (NSManagedObjectModel *)managedObjectModel { if (nil != _managedObjectModel) { return _managedObjectModel; } _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil]; return _managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (nil != _persistentStoreCoordinator) { return _persistentStoreCoordinator; } NSString *storeType = NSSQLiteStoreType; NSString *storeName = @"model.sqlite"; NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:storeName]]; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel]; NSError *error = nil; if (![_persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nil URL:storeURL options:nil error:&error]) { NSLog(@"Error : %@\n", [error localizedDescription]); NSAssert1(YES, @"Failed to create store %@ with NSSQLiteStoreType", [storeURL path]); } return _persistentStoreCoordinator; } #pragma mark - #pragma mark Application's Documents Directory - (NSString *)applicationDocumentsDirectory { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; return basePath; } 

应用程序启动后:

 @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. if (self.managedObjectContext) { ; } return YES; } 

当我点击button时:

 - (IBAction)runButtonDidClick:(id)sender { /** * Access the moc using different threads to make deadlock. */ [self runSave]; } - (void)runSave { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *moc = appDelegate.managedObjectContext; if (moc) { for (int j = 0; j < 10000; ++j) { People *people = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:moc]; people.name = @"noname"; } NSLog(@"**********IN SAVE %@", [NSThread currentThread]); NSError *error = nil; if ([moc save:&error]) { ; } NSLog(@"**********OUT SAVE %@", [NSThread currentThread]); } }); } 

点击运行button有时候,也许2或3或4 …它崩溃

我无法弄清楚为什么…感谢您的帮助。

在这里输入图像说明

在这里输入图像说明

核心数据应该始终工作在线程巫婆moc。 performBlockperformBlockAndWait唯一的工作就是保证线程安全。 随着它插入到核心数据将始终运行在正确的线程。 你可以在你想要的任何线程上定义moc – performBlock总是select正确的。

所以:

 [self.managedObjectContext performBlock:^{ for(NSDictionary *dic in arr) { //inserting here! } }]; 

在你的情况下:

 - (void)runSave { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *moc = appDelegate.managedObjectContext; if (moc) { [moc performBlock:^{ for (int j = 0; j < 10000; ++j) { People *people = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:moc]; people.name = @"noname"; } NSError *error = nil; if ([moc save:&error]) { ; } }]; } }); }