创建时
1. 基本原理图
AppDelegate
#pragma mark - Core Data stack
// 被管理对象上下文(数据管理器) 相当于一个临时数据库
@synthesize managedObjectContext = _managedObjectContext;
// 被管理对象模型(数据模型器)
@synthesize managedObjectModel = _managedObjectModel;
// 持久化存储助理(数据连接器) 整个 coredata 框架的核心
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
// 获取真实文件的存储路径
- (NSURL *)applicationDocumentsDirectory {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.hk.CoreData" in the application's documents directory.
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (NSManagedObjectModel *)managedObjectModel {
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData.sqlite"];
NSError *error = nil;
NSString *failureReason = @"There was an error creating or loading the application's saved data.";
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// Report any error we got.
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
#pragma mark - Core Data Saving support
// 把我们临时数据库中进行的改变进行永久保存
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
ViewController
#import "ViewController.h"
#import "AppDelegate.h"
#import "Cloths.h"
@interface ViewController () <UITableViewDataSource,UITableViewDelegate>
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) NSMutableArray *dataArray;
// 声明一个 AppDelegate 对象属性, 用来调用类中的属性, 比如管理对象上下文
@property (nonatomic, strong) AppDelegate *myAppDelegate;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArray = [NSMutableArray array];
self.myAppDelegate = [UIApplication sharedApplication].delegate;
// 查询数据
// 1. NSFetchResqust对象
NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"Cloths"];
// 2. 设置排序
// 2.1 创建排序描述对象(根据模型中的属性排序)
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"price" ascending:YES];
request.sortDescriptors = @[sortDescriptor];
// 执行这个查询
// 捕捉 error 信息
NSError *error = nil;
NSArray *resultArray = [self.myAppDelegate.managedObjectContext executeFetchRequest:request error: &error];
// 给数据源数组添加数据
[self.dataArray addObjectsFromArray:resultArray];
}
// 插入数据 (tabbar 点击事件)
- (IBAction)addModel:(id)sender
{
// 插入数据
// 创建实体描述对象
NSEntityDescription *description = [NSEntityDescription entityForName:@"Cloths" inManagedObjectContext:self.myAppDelegate.managedObjectContext];
// 1. 先创建一个模型对象
Cloths *cloth = [[Cloths alloc]initWithEntity: description insertIntoManagedObjectContext:self.myAppDelegate.managedObjectContext];
// 属性赋值
cloth.name = @"Puma";
int price = arc4random() % 1000 + 1;
cloth.price = [NSNumber numberWithInt:price];
// 插入数据源数组
[self.dataArray addObject:cloth];
// 插入 UI
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.dataArray.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
// 对数据管理器中的更改进行永久存储
[self.myAppDelegate saveContext];
}
// 返回多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.dataArray.count;
}
// cell的设置
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
Cloths *cloth = self.dataArray[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:@"%@ -- %@", cloth.name, cloth.price];
return cell;
}
// 允许 table可以编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// 删除数据
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// 先取出数据
Cloths *cloth = self.dataArray[indexPath.row];
// 删除数据源
[self.dataArray removeObject:cloth];
// 删除数据管理器中的数据
[self.myAppDelegate.managedObjectContext deleteObject:cloth];
// 将进行的更改进行永久保存
[self.myAppDelegate saveContext];
// 删除单元格
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
// cell 点击方式 修改数据
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1. 找到模型对象
Cloths *cloth = self.dataArray[indexPath.row];
cloth.name = @"Nick";
// 刷新单元行
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
// 永久保存更改数据 saveContext方法
[self.myAppDelegate saveContext];
}