您的位置:首页 > 其它

关于CoreData的多线程安全问题

2015-12-16 14:17 417 查看
/*

_ooOoo_

o8888888o

88" . "88

(| -_- |)

O\ = /O

____/`---'\____

.' \\| |// `.

/ \\||| : |||// \

/ _||||| -:- |||||- \

| | \\\ - /// | |

| \_| ''\---/'' | |

\ .-\__ `-` ___/-. /

___`. .' /--.--\ `. . __

."" '< `.___\_<|>_/___.' >'"".

| | : `- \`.;`\ _ /`;.`/ - ` : | |

\ \ `-. \_ __\ /__ _/ .-` / /

======`-.____`-.___\_____/___.-`____.-'======

`=---='

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

佛祖保佑
永无BUG

佛祖镇楼 BUG辟易

*/

CoreData中的NSManagedObjectContext在多线程中不安全,如果想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext,

,每个NSManagedObjectContext对象实例都可以使用同一个NSPersistentStoreCoordinator实例,这个实例可以很安全的顺序访问永久存储,这是因为NSManagedObjectContext会在便用NSPersistentStoreCoordinator前上锁。

ios5.0为NSManagedObjectContext提供了initWithConcurrentcyType方法,其中的一个NSPrivateQueueConcurrencyType,会自动的创建一个新线程来存放NSManagedObjectContext而且它还会自动创建NSPersistentStoreCoordinator,AppDelegate和前一章的一样,ios5.0之前的可以用GCD来实现



[plain] view
plaincopyprint?

- (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(), ^{

//

// });

// });

}

通知中心

[plain] view
plaincopyprint?

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

// }

//

// }];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: