ボタンが 1 つしかない、非常に単純な Core Data デモがあります。
「実行」ボタンをクリックすると、アプリはグローバル キューで実行されている for ループに 10,000 個のオブジェクトを作成します。
詳細の更新: for ループをメイン スレッドに配置すると、正常に実行されます。
私の意図の更新: MOC がスレッドセーフではないことはわかっていますが、Apple docによると、シリアル キューを使用して 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回...クラッシュします
理由がわかりませんでした...助けてくれてありがとう。

