CoreData中的NSManagedObjectContext在多線程中不安全,若是想要多線程訪問CoreData的話,最好的方法是一個線程一個NSManagedObjectContext,ios
,每一個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(), ^{
- //
- // });
- // });
- }
通知中心app
- -(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];
- });
- }
其實也能夠不用通知就是把 下面的內容不讓其註釋,同時註釋通知中心就好了 async
// context.parentContext=_myAppDelegate.managedObjectContext;ide
// //main threadoop
// [_myAppDelegate.managedObjectContext performBlock:^{spa
// NSError* error;.net
// if (![_myAppDelegate.managedObjectContext save:&error]) {線程
// NSLog(@"error is %@",error);
// }
//
// }];