CoreData的使用以及coreData中的多线程问题
2016-04-28 21:47
597 查看
CoreData的使用
1.coreData简介
coreData是苹果对sqlite的封装,不用操作sqlite语句,他提供了对象关系映射功能,能将oc对象转化成数据,保存在sqlite中,也能将保存的数据还原成o对象;
coredata有两种队列:私有队列,主队列
coreData中的主要包括这几个部分:管理对象上下文,数据持久化协调器,模型文件(包含实体,实体对应的是实体类),
2.coreData的使用
// 1.创建模型文件 [相当于一个数据库里的所有表]
// 2.添加实体(可以添加多个实体) ,添加相应实体的属性[相当于数据库中添加了一张表]
// 3.创建对应的实体类(可能有多个实体) [相当于模型]
// 4.生成管理对象上下文 并关联模型文件生成数据库
/*
* 关联的时候,如果本地没有数据库文件,Coreadata自己会创建
*/
// 创建上下文
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
// model模型文件
// NSManagedObjectModel *model =[NSManagedObjectModel mergedModelFromBundles:nil];//使用这个方法,如果
bundles为nil会把bundles里面的所有模型文件的表放在一个数据库中
//使用下面这个方法,是把一个模型文件对应一个数据库
NSURL *companyURL = [[NSBundlemainBundle]URLForResource:modelNamewithExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModelalloc]initWithContentsOfURL:companyURL];
// 持久化存储调度器
// 持久化,把数据保存到一个文件,而不是内存
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
// 告诉Coredata数据库的名字和路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *sqlitePath = [doc stringByAppendingPathComponent:@"company.sqlite"];
NSLog(@"%@",sqlitePath);
[store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURLfileURLWithPath:sqlitePath] options:nil error:nil];
//设置上下文的持久化调度器
context.persistentStoreCoordinator = store;
_context = context;
}
==========
//使用这个方法是把不同的模型文件的表放到不同的数据库中
-(NSManagedObjectContext *)setupContextWithModelName:(NSString *)modelName{
// 1.创建模型文件[相当于一个数据库里的表]
// 2.添加实体[一张表]
// 3.创建实体类 [相当模型]
// 4.生成上下文关联模型文件生成数据库
/*
* 关联的时候,如果本地没有数据库文件,Coreadata自己会创建
*/
//
上下文
NSManagedObjectContext *context = [[NSManagedObjectContextalloc]init];
// 上下文关连数据库
// model模型文件
NSURL *companyURL = [[NSBundlemainBundle]URLForResource:modelNamewithExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModelalloc]initWithContentsOfURL:companyURL];
// 持久化存储调度器
// 持久化,把数据保存到一个文件,而不是内存
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinatoralloc]initWithManagedObjectModel:model];
//
告诉Coredata数据库的名字和路径
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];
NSString *sqliteName = [NSStringstringWithFormat:@"%@.sqlite",modelName];
NSString *sqlitePath = [doc
stringByAppendingPathComponent:sqliteName];
NSLog(@"%@",sqlitePath);
[store addPersistentStoreWithType:NSSQLiteStoreTypeconfiguration:nilURL:[NSURLfileURLWithPath:sqlitePath]options:nilerror:nil];
context.persistentStoreCoordinator = store;
return context;
}
==========
// 数据库的操作 CURD Create Update Read Delete
#pragma mark -----增
// 通过模型文件中的实体创建一个员工对象
//Employee *emp = [[Employee alloc] init];
Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee"inManagedObjectContext:_context];
emp.name = @"wangwu";
emp.height = @1.80;
emp.birthday = [NSDate date];
// 直接保存数据库
NSError *error = nil;
[_context save:&error];
if (error) {
NSLog(@"%@",error);
}
#pragma mark ----查
// 1.FectchRequest 创建抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 2.设置过滤条件
// 查找zhangsan
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name
= %@",
@"zhangsan"];
request.predicate = pre;
// 3.设置排序
// 身高的升序排序
NSSortDescriptor *heigtSort = [NSSortDescriptor sortDescriptorWithKey:@"height"ascending:NO];
request.sortDescriptors = @[heigtSort];
// 4.执行请求
NSError *error = nil;
NSArray *emps = [_context executeFetchRequest:request error:&error];
if (error) {
NSLog(@"error");
}
//NSLog(@"%@",emps);
//遍历员工
for (Employee *emp in emps) {
NSLog(@"名字 %@ 身高 %@ 生日 %@",emp.name,emp.height,emp.birthday);
}
#pragma mark -----改
// 1.查找到zhangsan
// 1.1FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 1.2设置过滤条件
// 查找zhangsan
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name
= %@",
@"zhangsan"];
request.predicate = pre;
// 1.3执行请求
NSArray *emps = [_context executeFetchRequest:request error:nil];
// 2.更新身高
for (Employee *e in emps) {
e.height = @2.0;
}
// 3.保存
[_context save:nil];
#pragma mark ------删
// 1.查找lisi
// 1.1FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 1.2设置过滤条件
// 查找zhangsan
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name
= %@",
@"lisi"];
request.predicate = pre;
// 1.3执行请求
NSArray *emps = [_context executeFetchRequest:request error:nil];
// 2.删除
for (Employee *e in emps) {
[_context deleteObject:e];
}
// 3.保存
[_context save:nil];
====================================
模糊查询:
// 1.FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
//设置身高的升序排序
NSSortDescriptor *heigtSort = [NSSortDescriptor sortDescriptorWithKey:@"height"ascending:NO];
request.sortDescriptors = @[heigtSort];
// 模糊查询
// 名字以"wang"开头
// NSPredicate *pre = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@",@"wangwu1"];
// request.predicate = pre;
// 名字以"1"结尾
// NSPredicate *pre = [NSPredicate predicateWithFormat:@"name ENDSWITH %@",@"1"];
// request.predicate = pre;
// 名字包含"wu1"
// NSPredicate *pre = [NSPredicate predicateWithFormat:@"name CONTAINS %@",@"wu1"];
// request.predicate = pre;
// like
//以wangwu1*结尾
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name
like %@",@"*wu12"];
//以wangwu1开头
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name
like %@",@"wu12*"];
//匹配正则表达式
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name
like %@",@"正则表达是语句"];
request.predicate = pre;
// 4.执行请求
NSError *error = nil;
NSArray *emps = [_context executeFetchRequest:request error:&error];
====================================
分页查询
// 1.FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 设置身高的升序排序
NSSortDescriptor *heigtSort = [NSSortDescriptorsortDescriptorWithKey:@"height"ascending:NO];
request.sortDescriptors =
@[heigtSort];
//
总有共有15数据
//
每次获取6条数据
//
第一页 0,6
//
第二页 6,6
//
第三页 12,6 3条数据
//
分页查询 limit 0,5
//
分页的起始索引
request.fetchOffset =
12;
//
分页的条数
request.fetchLimit =
6;
// 4.执行请求
NSError *error =
nil;
NSArray *emps = [_context executeFetchRequest:requesterror:&error];//执行查询
++++++++++++++++++++++++++++
直接创建查询结果控制器查询
//懒加载
-(NSFetchedResultsController *)fetchController
{
if (_fetchController ==
nil) {
//查询请求
NSFetchRequest *fetchrequest = [[NSFetchRequest
alloc]init];
//1.获取实体描述
fetchrequest.entity = [NSEntityDescription
entityForName:@"XMPPUserCoreDataStorageObject"
inManagedObjectContext:[XMPPRosterCoreDataStorage
sharedInstance].mainThreadManagedObjectContext];
//获取实体描述
<code class="hljs vhdl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"> NSEntityDescription *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">entity</span> = [NSEntityDescription entityForName:TableName inManagedObjectContext:<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">context</span>];</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"></ul>
//2.谓词
NSPredicate *pre = [NSPredicate
predicateWithFormat:@"subscription = %@",@"both"];
[fetchrequest setPredicate:pre];
//3.排序
NSSortDescriptor *sort = [NSSortDescriptor
sortDescriptorWithKey:@"jidStr"
ascending:YES];
fetchrequest.sortDescriptors =
@[sort];
//创建对象查询控制器对象
_fetchController = [[NSFetchedResultsController
alloc]initWithFetchRequest:fetchrequest
managedObjectContext:[XMPPRosterCoreDataStorage
sharedInstance].mainThreadManagedObjectContext
sectionNameKeyPath:nil
cacheName:@"contacts"];
//代理
_fetchController.delegate =
self;
}
return
_fetchController;
}
-(NSArray *)contactEntity
{
if (_contactEntity ==
nil) {
_contactEntity = [NSArray
array];
}
return
_contactEntity;
}
- (void)viewDidLoad {
[super
viewDidLoad];
//
查询数据
[self.fetchController
performFetch:nil];//执行查询
self.contactEntity =
self.fetchController.fetchedObjects;
}
//查询控制器请求代理方法
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
//重新获取数据
self.contactEntity =
self.fetchController.fetchedObjects;
//刷新
[self.tableView
reloadData];
}
+++++++++++++++++++++++++++++
===================
//对数组的排序
NSSortDescriptor *heigtSort = [NSSortDescriptorsortDescriptorWithKey:@"height"ascending:NO];
// NSArray *resultArr=[arr sortedArrayUsingDescriptor:@[height]];
==============================================
CoreData中的多线程问题
1.一种比较好的iOS模式就是使用一个NSPersistentStoreCoordinator,以及两个独立的Contexts,一个context负责主线程与UI协作,一个context在后台负责耗时的处理,用Notifications的方式通知主线程的NSManagedObjectContext进行mergeChangesFromContextDidSaveNotification操作 2.后台线程做读写更新,而主线程只读 3.CoreData中的NSManagedObjectContext在多线程中不安全,如果想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext,每个NSManagedObjectContext对象实例都可以使用同一个NSPersistentStoreCoordinator实例,这个实例可以很安全的顺序访_问永久存储,这是因为NSManagedObjectContext会在便用NSPersistentStoreCoordinator前上锁。ios5.0为NSManagedObjectContext提供了initWithConcurrentcyType方法,其中的一个NSPrivateQueueConcurrencyType,会自动的创建一个新线程来存放NSManagedObjectContext而且它还会自动创建NSPersistentStoreCoordinator,
CoreData与多线程
为了在查询数据的时候不让界面停滞,使用多线程是不可避免,一般我们会用thread,串行线程或者并发线程。
coredata与多线程交互的时候,每个线程都必须拥有一个manager context对象,一般有两种方式:
1.每一个线程使用私有的manager context,共享一个 persistent store coordinator
2.每个线程使用私有的manager context和私有的persistent store coordinator
对于这两种方式,我们比较推荐使用第一钟方式,因为使用第二种方式的会消耗我们更多的内存,所以推荐使用第一种。
CoreData里面还带有一个通知NSManagedObjectContextDidSaveNotification,主要监听NSManagedObjectContext的数据是否改变,并合并数据改变到相应context
相关文章推荐
- DAG之硬币问题DP(最长路及其字典序)
- Linux文件系统选择
- Shiro登录校验
- mysql dumpfile与outfile函数的区别
- 关于Samba的SELiunx配置
- MyBatis 最常见错误,启动时控制台无限输出日志
- POJ 2774(后缀数组的应用)
- 纯css,div隐藏滚动条,保留鼠标滚动效果。
- PAT-B 1019. 数字黑洞
- 关于建立时间和保持时间
- 61. Rotate List
- ios开发总结之UIImageView常用属性
- JavaScript与OC的相互调用
- 懒人爱家务_SoundPool
- 你真的了解Android Notification吗?
- 如何使 类的成员函数作为回调函数
- 个人工作总结10
- 我理解的设计模式:工厂模式
- VisionMobile:2016年IoT大趋势(笔记)(四)从联网汽车到软件定义交通
- Android小错误收集