关于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来实现
![](http://img.blog.csdn.net/20130716165739375?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hlbjUwNTM1ODExOQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
[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);
// }
//
// }];
_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);
// }
//
// }];
相关文章推荐
- iOS WebP转换工具
- 表选取重复行数据中的一行
- 当以一个字符串为正则表达式时
- Mybatis步步进阶(三)——1:N关系配置 && 动态SQL拼接
- Java实现Excel导入数据库,数据库中的数据导入到Excel
- Android音频系统之AudioFlinger(四)
- oracle查看锁表进程,杀掉锁表进程
- 中间件-apache卸载步骤
- Mybatis步步进阶(二)——SQL的基本配置与执行
- Array与List的简单应用
- asp.net 发送邮件
- excel批量导入优化
- 利用余数选择特殊位置元素
- Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V
- Mybatis步步进阶(一)——环境搭建+创建数据库连接
- iOS应用发布流程(三)------构建版本,上传Xcode程序至App Store
- 杭电acm1115
- 内存泄露从入门到精通三部曲之基础知识篇
- 更新Xcode插件不能用啦
- Redis搭建入门详解文档