在《Core Data Programming Guide》文档的Concurrency with Core Data这一章节中提到了“Use Thread Confinement to Support Concurrency”,这里的“Thread”还包含serial operation queue和dispatch queue。
我目前的理解是MOC会负责对PSC进行加锁解锁,这些动作需要保证有序地得到执行,如果两个thread同时访问一份context,尤其是其中一个进行写操作,另一个进行读操作,就很容易发生死锁:
- (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) { NSString *threadPtr = [NSString stringWithFormat:@"%p", [NSThread currentThread]]; [_threadDict setObject:@"Running Thread" forKey:threadPtr]; 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]); } }); } - (void)runFetch { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *moc = appDelegate.managedObjectContext; if (moc) { NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; [fetchRequest setEntity:[NSEntityDescription entityForName:@"People" inManagedObjectContext:moc]]; NSLog(@"~~~~~~~~~~IN FETCH %@", [NSThread currentThread]); NSError *error = NULL; NSArray *array = [moc executeFetchRequest:fetchRequest error:&error]; if (array) { ; } NSLog(@"~~~~~~~~~~OUT FETCH %@", [NSThread currentThread]); } }); }
死锁的表现为: