我有一个非常简单的 Core Data 演示,其中只有一个按钮。
当我单击“运行”按钮时,应用程序在 for 循环中创建 10,000 个对象,该循环在全局队列中运行。
更新更多细节:如果我将 for 循环放在主线程中,它运行良好。
更新我的意图:我知道 MOC 不是线程安全的,但是根据Apple 文档,我们也可以使用串行队列来访问 MOC,并且串行队列使用多个线程。
在这里,我创建了核心数据堆栈:
#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 次......它崩溃了
我不知道为什么...感谢您的帮助。