Основные данные: вставка объектов, разбитых в глобальной очереди

У меня очень простая демо-версия Core Data, в которой есть только одна кнопка.

Когда я нажимаю кнопку «запустить», приложение создает 10 000 объектов в цикле for, который выполняется в глобальной очереди .

Обновление для более подробной информации: если я помещаю for-loop в основной поток, он работает хорошо.

Обновление для моих целей: я знаю, что MOC не является потокобезопасным, но, согласно документу Apple , мы также можем использовать последовательную очередь для доступа к MOC, а в последовательной очереди используется несколько потоков.

Здесь я создаю стек Core Data:

#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; } 

Когда я нажимаю кнопку:

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

Для нажатия кнопки запуска несколько раз, может быть, 2 или 3 или 4 … Сбой

Я не мог понять, почему … Спасибо за любую помощь.

введите описание изображения здесь

введите описание изображения здесь

One Solution collect form web for “Основные данные: вставка объектов, разбитых в глобальной очереди”

Основные данные должны всегда работать над потоком, который имеет moc. единственная работа для performBlock и performBlockAndWait – это забота о безопасности потоков. При этом вставка в Core Data всегда будет работать в правильном потоке. Вы можете определить moc для любого потока, который вы хотите – performBlock всегда выбирает правильный.

Так:

 [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]) { ; } }]; } }); } 
  • Помогает ли комплект спрайтов в фоновом режиме или в основном потоке? Как это работает?
  • Можно ли использовать объекты класса NSManagedObject в качестве моделей?
  • Очереди NSRunLoop и GCD
  • ios development: сохраненный файл не отображается в itunes
  • Изменить цвет заголовка кнопки в UIAlertView
  • Как принять пожертвования Paypal на iPhone iOS?
  • Обновление приложения iOS, как обновить plist в комплекте?
  • Проверка, что Bluetooth отключен на iOS 5 без BluetoothManager
  • запуск CABasicAnimation последовательно
  • iOS 7, iPhone, датчик приближения
  • Я делаю правильную вещь, чтобы преобразовать децибел с -120 - 0 до 0 - 120
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.