CoreData多线程安全
CoreData中的NSManagedObjectContext在多线程中不安全,如果想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext,
,每个NSManagedObjectContext对象实例都可以使用同一个NSPersistentStoreCoordinator实例,这个实例可以很安全的顺序访问永久存储,这是因为NSManagedObjectContext会在便用NSPersistentStoreCoordinator前上锁。
ios5.0为NSManagedObjectContext提供了initWithConcurrentcyType方法,其中的一个NSPrivateQueueConcurrencyType,会自动的创建一个新线程来存放NSManagedObjectContext而且它还会自动创建NSPersistentStoreCoordinator,AppDelegate和前一章的一样,ios5.0之前的可以用GCD来实现
- (IBAction)addIntoDataSource:(id)sender { // User* user=(User *)[NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.myAppDelegate.managedObjectContext]; // [user setName:_nameText.text]; // [user setAge:[NSNumber numberWithInteger:[_ageText.text integerValue]]]; // [user setSex:_sexText.text]; // // Address* address=(Address *)[NSEntityDescription insertNewObjectForEntityForName:@"Address" inManagedObjectContext:self.myAppDelegate.managedObjectContext]; // [address setIdentify:[NSNumber numberWithInteger:[_identyText.text integerValue]]]; // [address setHomelocation:@"咸宁"]; // NSError* error; // BOOL isSaveSuccess=[_myAppDelegate.managedObjectContext save:&error]; // if (!isSaveSuccess) { // NSLog(@"Error:%@",error); // }else{ // NSLog(@"Save successful!"); // } NSManagedObjectContext* context=[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; // context.parentContext=_myAppDelegate.managedObjectContext; [context performBlock:^{ //background thread [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mocDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil]; User* user=(User *)[NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.myAppDelegate.managedObjectContext]; [user setName:_nameText.text]; [user setAge:[NSNumber numberWithInteger:[_ageText.text integerValue]]]; [user setSex:_sexText.text]; NSError* error; if (![context save:&error]) { NSLog(@"Error is %@",error); } // //main thread // [_myAppDelegate.managedObjectContext performBlock:^{ // NSError* error; // if (![_myAppDelegate.managedObjectContext save:&error]) { // NSLog(@"error is %@",error); // } // // }]; }]; // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // // dispatch_sync(dispatch_get_main_queue(), ^{ // // }); // }); }
-(void)mocDidSaveNotification:(NSNotification *)notification { NSManagedObjectContext* saveContext=[notification object]; if (_myAppDelegate.managedObjectContext==saveContext) { return; } if (_myAppDelegate.managedObjectContext.persistentStoreCoordinator!=saveContext.persistentStoreCoordinator) { return; } dispatch_sync(dispatch_get_main_queue(), ^{ [_myAppDelegate.managedObjectContext mergeChangesFromContextDidSaveNotification:notification]; }); }
其实也可以不用通知就是把 下面的内容不让其注释,同时注释通知中心就行了
// context.parentContext=_myAppDelegate.managedObjectContext; // //main thread // [_myAppDelegate.managedObjectContext performBlock:^{ // NSError* error; // if (![_myAppDelegate.managedObjectContext save:&error]) { // NSLog(@"error is %@",error); // } // // }];