您的位置:首页 > 其它

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: