CoreData初级使用教程
iOS中的CoreData用起来很是方便,比起SQLite又臭又长而且容易出错的语句简直不能再好用,这也是苹果官方推荐使用的。今天抽空写个教程给大家参考,也方便自己温故知新。
一、准备工作
首先在建立工程时在“use Core Data”前面打钩

这样系统就会生成一个coreData相关的文件

然后我们点开这个类就会发现是一个表格结构的东东,这就是coreData的可视化建模,也是有一定逼格的。
然后我们点击左下方的Add Entity建立实体(可以理解为我们经常创建的类),并添加几个属性

好了,接下来就是CoreData牛逼的地方,我们选中CoreData对应的文件然后选择Xcode工具栏中的Editor->Create NSManagedObject Subclass...,系统就会生成该实体对应的类


二、正式使用
系统帮我们生成的类里面该有的不该有的系统已经帮我们弄好了,我们只管用就行了。接下来在要使用的类的头文件中导入该类以及appDelegate.h(方便调用CoreData方法)
#import "ViewController.h"
#import "AppDelegate.h"
#import "Person.h"
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource,UIGestureRecognizerDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
//用该属性调用CoreData命令
@property(nonatomic,strong)AppDelegate *appDelegate;
//存放要显示的数据
@property(nonatomic,strong)NSMutableArray *mutableArray;
@end
为了方便操作以及显示,我是通过storyboard给界面添加了一个增加数据的按钮,当然也可以直接用代码添加

tableView代理方法
//分区数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
//每个分区下的行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.mutableArray.count;
}
//定义cell内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//由于这里只是显示,所以不存在与CoreData交互
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
Person *person = self.mutableArray[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:@"姓名:%@,年龄%@",person.name,person.age];
cell.detailTextLabel.text = [NSString stringWithFormat:@"性别:%@",person.gender];
return cell;
}
增删改查操作
1 添加数据(按钮的回调方法)
//添加数据
- (IBAction)addData:(id)sender {
//建立一个实体描述文件
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.appDelegate.managedObjectContext];
//通过描述文件创建一个实体
Person * person = [[Person alloc]initWithEntity: entityDescription insertIntoManagedObjectContext:self.appDelegate.managedObjectContext];
person.name = @"帅哥";
person.gender = @"男";
//随机生成一个年龄
int age = arc4random()%20 + 1;
person.age = [NSNumber numberWithInt:age];
//添加到数据中
[self.mutableArray insertObject:person atIndex:0];
//调用持久化save方法保存到CoreData中
[self.appDelegate saveContext];
//添加到UI下面这句写成[self.tableView reloadData]也可以
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
}
2删除数据
//滑动后红色删除按钮上显示的文字
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
return @"删除";
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
//删除情况下
if (editingStyle == UITableViewCellEditingStyleDelete) {
Person *person = self.mutableArray[indexPath.row];
[self.mutableArray removeObject:person];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//删除CoreData中的数据
[self.appDelegate.managedObjectContext deleteObject:person];
//持久化一下
[self.appDelegate saveContext];
}
}
3修改数据
//修改数据
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Person *person = self.mutableArray[indexPath.row];
if ([person.gender isEqualToString:@"男"]) {
person.gender = @"女";
person.name = @"新名字";
[self.appDelegate saveContext];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
}
//词句代码作用为点击cell后的点击效果完成之后会消失,不会一直显示选中状态
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
4查询数据
查询数据这块,CoreData简直太6了,输入fet三个字母后然后根据系统提示按回车瞬间系统给你提供了半个屏幕的代码,简直太良心了,我们只需要把相关信息填进去就行

//查询数据
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.appDelegate.managedObjectContext];
[fetchRequest setEntity:entity];
// Specify criteria for filtering which objects to fetch
//谓词搜索
// NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age = 21", ];
// [fetchRequest setPredicate:predicate];
// Specify how the fetched objects should be sorted
//排序方法(这里为按照年龄升序排列)
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
NSError *error = nil;
NSArray *fetchedObjects = [self.appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(@"数据查询错误%@",error);
}else{
//查询到之后要你的操作代码
}
其他:
viewDidLoad中需要做的事情
估计很多人在做完以上操作后发现重新运行程序后界面上不显示数据,很大一部分原因是没有在viewDidLoad中将CoreData中的数据添加到数据源中,即,上述查询方法需在viewDidLoad中执行一次并添加到数据源中以供显示
//初始化
self.appDelegate = [UIApplication sharedApplication].delegate;
self.mutableArray = [NSMutableArray array];
//给数据源添加数据
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.appDelegate.managedObjectContext];
[fetchRequest setEntity:entity];
// Specify criteria for filtering which objects to fetch
// NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age = 21", ];
// [fetchRequest setPredicate:predicate];
// Specify how the fetched objects should be sorted
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
NSError *error = nil;
NSArray *fetchedObjects = [self.appDelegate.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(@"数据查询错误%@",error);
}else{
//将查询到的数据添加到数据源中
[self.mutableArray addObjectsFromArray:fetchedObjects];
}

三、调试(查看语句执行情况)
有些同学可能想看一下代码执行情况,这样也有助于调试,我们可以按照以下设置



这样设置完成之后,如果CoreData数据有变动,相关语句会在控制台打印出来

OVER