iOS App中数据管理框架Core Data的基本数据操作教程_IOS开发教程-查字典教程网
iOS App中数据管理框架Core Data的基本数据操作教程
iOS App中数据管理框架Core Data的基本数据操作教程
发布时间:2016-12-28 来源:查字典编辑
摘要:NSEntityDescription是实体描述对象,它可以类比如数据库中的表,NSEntityDescription存放的是表的结构信息。...

NSEntityDescription是实体描述对象,它可以类比如数据库中的表,NSEntityDescription存放的是表的结构信息。这些类都是一些抽象的结构类,并不存储实际每条数据的信息,具体的数据由NSManagedObject类来描述,我们一般会将实体类化继承于NSManagedObject。

Xocde工具提供了快捷的实体类化功能,还拿我们一开始创建的班级与学生实体来演示,点击.xcdatamodeld文件,点击Xcode工具上方导航栏的Editor标签,选择Creat NSManagedObject Subclass选项,在弹出的窗口中勾选要类化的实体,如下图:

这时,Xcode会自动为我们创建一个文件,这些文件中有各个类中属性的声明。

一、创建一条数据

使用如下代码进行数据的创建:

//读取数据模型文件

NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];

//创建数据模型

NSManagedObjectModel * mom = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];

//创建持久化存储协调者

NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:mom];

//数据库保存路径

NSURL * path =[NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]];

//为持久化协调者添加一个数据接收栈

/*

可以支持的类型如下:

NSString * const NSSQLiteStoreType;//sqlite

NSString * const NSXMLStoreType;//XML

NSString * const NSBinaryStoreType;//二进制

NSString * const NSInMemoryStoreType;//内存

*/

[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:path options:nil error:nil];

//创建数据管理上下文

NSManagedObjectContext * moc = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];

//关联持久化协调者

[moc setPersistentStoreCoordinator:psc];

//创建数据对象

/*

数据对象的创建是通过实体名获取到的

*/

SchoolClass * modelS = [NSEntityDescription insertNewObjectForEntityForName:@"SchoolClass" inManagedObjectContext:moc];

//对数据进行设置

modelS.name = @"第一班";

modelS.stuNum = @60;

//进行存储

if ([moc save:nil]) {

NSLog(@"新增成功");

}

NSLog(@"%@",[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]);

找到在打印出的路径,会发现里面多了一个sqlite文件,其中有一张表中添加进了一条数据。

二、查询数据

CoreData中通过查询请求来对数据进行查询操作,查询请求由NSFetchRequest来进行管理和维护。

NSFetchRequest主要提供两个方面的查询服务:

1.提供范围查询的相关功能

2.提供查询结果返回类型与排序的相关功能

NSFetchRequest中常用方法如下:

//创建一个实体的查询请求 可以理解为在某个表中进行查询

+ (instancetype)fetchRequestWithEntityName:(NSString*)entityName;

//查询条件

@property (nullable, nonatomic, strong) NSPredicate *predicate;

//数据排序

@property (nullable, nonatomic, strong) NSArray<NSSortDescriptor *> *sortDescriptors;

//每次查询返回的数据条数

@property (nonatomic) NSUInteger fetchLimit;

//设置查询到数据的返回类型

/*

typedef NS_OPTIONS(NSUInteger, NSFetchRequestResultType) {

NSManagedObjectResultType= 0x00,

NSManagedObjectIDResultType= 0x01,

NSDictionaryResultType NS_ENUM_AVAILABLE(10_6,3_0) = 0x02,

NSCountResultTypeNS_ENUM_AVAILABLE(10_6,3_0) = 0x04

};

*/

@property (nonatomic) NSFetchRequestResultType resultType;

//设置查询结果是否包含子实体

@property (nonatomic) BOOL includesSubentities;

//设置要查询的属性值

@property (nullable, nonatomic, copy) NSArray *propertiesToFetch;

在SchoolClass实体中查询数据,使用如下的代码:

//创建一条查询请求

NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];

//设置条件为 stuNum=60的数据

[request setPredicate:[NSPredicate predicateWithFormat:@"stuNum == 60"]];

//进行查询操作

NSArray * res = [moc executeFetchRequest:request error:nil];

NSLog(@"%@",[res.firstObject stuNum]);

进行数据初始化

NSFetchedResultsController的初始化需要一个查询请求和一个数据操作上下文。代码示例如下:

//遵守协议

@interface ViewController ()<NSFetchedResultsControllerDelegate>

{

//数据桥接对象

NSFetchedResultsController * _fecCon;

}

@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

//进行初始化操作

NSURL *modelUrl = [[NSBundle mainBundle]URLForResource:@"Model" withExtension:@"momd"];

NSManagedObjectModel * mom = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelUrl];

NSPersistentStoreCoordinator * psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:mom];

NSURL * path =[NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"CoreDataExample.sqlite"]];

[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:path options:nil error:nil];

NSManagedObjectContext * moc = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];

[moc setPersistentStoreCoordinator:psc];

NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"SchoolClass"];

//设置数据排序

[request setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"stuNum" ascending:YES]]];

//进行数据桥接对象的初始化

_fecCon = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:nil cacheName:nil];

//设置代理

_fecCon.delegate=self;

//进行数据查询

[_fecCon performFetch:nil];

}

@end

用于初始化NSFecthedResultsController的数据请求对象必须设置一个排序规则。在initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:方法中,如果设置第三个参数,则会以第三个参数为键值进行数据的分区。当数据发生变化时,将通过代理进行方法的回调。

三、与UITableView进行数据绑定

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"cellid"];

if (!cell) {

cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellid"];

}

//获取相应数据模型

SchoolClass * obj = [_fecCon objectAtIndexPath:indexPath];

cell.textLabel.text = obj.name;

cell.detailTextLabel.text = [NSString stringWithFormat:@"有%@人",obj.stuNum];

return cell;

}

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{

return [_fecCon sections].count;

}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

id<NSFetchedResultsSectionInfo> info = [_fecCon sections][section];

return [info numberOfObjects];

}

效果如下:

四、将数据变化映射到视图

//数据将要改变时调用的方法

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

{

//开启tableView更新预处理

[[self tableView] beginUpdates];

}

//分区数据改变时调用的方法

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type

{

//判断行为类型

switch(type) {

//插入新分区

case NSFetchedResultsChangeInsert:

[[self tableView] insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

break;

//删除分区

case NSFetchedResultsChangeDelete:

[[self tableView] deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];

break;

//移动分区

case NSFetchedResultsChangeMove:

//更新分区

case NSFetchedResultsChangeUpdate:

break;

}

}

//数据改变时回调的代理

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath

{

switch(type) {

//插入数据

case NSFetchedResultsChangeInsert:

[[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

break;

//删除数据

case NSFetchedResultsChangeDelete:

[[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

break;

//更新数据

case NSFetchedResultsChangeUpdate:

[self reloadData];

break;

//移动数据

case NSFetchedResultsChangeMove:

[[self tableView] deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

[[self tableView] insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

break;

}

}

//数据更新结束调用的代理

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

{

[[self tableView] endUpdates];

}

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新IOS开发学习
    热门IOS开发学习
    编程开发子分类