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);

//            }

//            

//        }];

 

posted @ 2015-10-14 15:56  十点听风  阅读(165)  评论(0编辑  收藏  举报