工程中引入CoreData步骤:
1.添加CoreData Framework框架
2.创建Data Model(数据模型)
New File -> Core Data -> Data Model
3.添加实体表和属性
Data Model -> Add Entity ->Add Attributes添加字段属性
4.创建实体对象类
方法1:选中Entity:Xcode的菜单Editor -> Create NSManagedObject SubClass…
这样可以自动生成与实体表相关连的实体类.h.m.
选择实体表 查看属性,名称和关联类名应该都已经是自动关联成功的了。
方法2:如果手动创建实体类.h.m文件,那么要手动实现与实体表的关联,否则实体表默认关联NSManagedObject,这样就会造成错误。
PS:个人项目中曾出现过类似的错误,生成实体之后实体调用它的实例方法会崩溃,实体不能识别它的实体方法。
5.编写coreData代码
首先说明,这部分编写的代码是为了引入CoreData到工程中,可以新建一个包含CoreData的空白工程,然后完全Copy其AppDegate中的引入CoreData方法即可。
代码部分:
<1>AppDelegate中引入头文件
#import <CoreData/CoreData.h>
<2>增加属性及方法声明
// 上下文对象 @property(readonly,retain,nonatomic)NSManagedObjectContext *managedObjectContext;
// 数据模型
@property (readonly,retain,nonatomic)NSManagedObjectModel *managedObjectModel;
// 协调者
@property (readonly,retain,nonatomic)NSPersistentStoreCoordinator *persistentStoreCoordinator;
// 在应用程序终止的时候会调用该方法
- (void)saveContext;
// 得到应用程序的 Documents 路径, 将数据库存在此目录下
- (NSURL *)applicationDocumentsDirectory;
<3>AppDelegate.m 文件会多出如下几个方法:
- (void)applicationWillTerminate:(UIApplication *)application
{
// 保存上下文对象的方法在此调用(程序结束的时候)
[self saveContext];
}
#pragma makr - save context
- (void)saveContext
{
// 程序意外终止就会调用此方法
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
AppDelegate.m中实现CoreData方法
#pragma mark - Core Data stack
- (NSManagedObjectContext *)managedObjectContext
{
// 创建上下文对象
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
// 创建数据模型
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataDemo02" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
// 创建协调者,也就是存储区
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataDemo02.sqlite"];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
- (NSURL *)applicationDocumentsDirectory
{
// 得到 Documents 目录
return [[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
第二.CoreData的增删查:(以persion为例)
写入数据
- (void)insertData
{
// 创建实体 Person * newPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; // 赋值
if (newPerson != nil) {
newPerson.firstName = @"Zero"; newPerson.lastName = @"Hour"; newPerson.age = [NSNumber numberWithInt:20]; // 保存数据 NSError * savingError = nil; if ([self.managedObjectContext save:&savingError]) { NSLog(@"success"); }else { NSLog(@"failed to save the context error = %@", savingError); }
}else {
NSLog(@"failed to create the new person"); }
}
- 删除数据
(void)deleteData
{
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@”Person” inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];NSError * requestError = nil;
NSArray * persons = [self.managedObjectContext executeFetchRequest:fetchRequest error:&requestError];if ([persons count] > 0) {
Person * lastPerson = [persons lastObject];
// 删除数据
[self.managedObjectContext deleteObject:lastPerson];
if ([lastPerson isDeleted]) {NSLog(@"successfully deleted the last person"); NSError * savingError = nil; if ([self.managedObjectContext save:&savingError]) { NSLog(@"successfully saved the context"); }else { NSLog(@"failed to save the context error = %@", savingError); }
}else {
NSLog(@"failed to delete the last person");
}
}else {NSLog(@"could not find any person entity in the context");
}
}
更改数据
- (void)updateData { NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; NSError * requestError = nil; NSArray * persons = [self.managedObjectContext executeFetchRequest:fetchRequest error:&requestError]; if ([persons count] > 0) { Person * lastPerson = [persons lastObject]; // 更新数据 lastPerson.firstName = @"Hour"; lastPerson.lastName = @"Zero"; lastPerson.age = @21; NSError * savingError = nil; if ([self.managedObjectContext save:&savingError]) { NSLog(@"successfully saved the context"); }else { NSLog(@"failed to save the context error = %@", savingError); } }else { NSLog(@"could not find any person entity in the context"); } }
查询数据
- (void)findData
{
[fetchRequest setEntity:entity];NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription * entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
// 设置排序条件
NSSortDescriptor * ageSort = [[NSSortDescriptor alloc] initWithKey:@”age” ascending:YES];
NSSortDescriptor * firstNameSort = [[NSSortDescriptor alloc] initWithKey:@”firstName” ascending:YES];
NSArray * sortDescriptors = @[ageSort, firstNameSort];
[fetchRequest setSortDescriptors:sortDescriptors];// 设置查询条件
NSPredicate * agePre = [NSPredicate predicateWithFormat:@”age > 18”];
[fetchRequest setPredicate:agePre];NSError * requestError = nil;
NSArray * persons = [self.managedObjectContext executeFetchRequest:fetchRequest error:&requestError];
int counter = 0;
for (Person * thisPerson in persons) {NSLog(@"person-->%d, firstName = %@, lastName = %@, age = %d", counter, thisPerson.firstName, thisPerson.lastName, [thisPerson.age intValue]); counter ++; }
}
- (void)findData
第三.实体表关系及属性:
增加实体表关系:Entity -> Add RelationShip 或者 选中Entity,按住Control键,拖向创建关系的表。这种方式会自动创建反相关联
<1>关系名称必须首字母小写
<2>Apple建议每一个关系都创建一个反向关系(inverse)。没有反向关联的话会有一个数据库警告
<3>To-Many Relationship属性,代表着一对多的关系,一个实体可以关联多个。
<4>Delete Rule选项可以选择Cascade,实现级联删除,表示在使用Core Data删除表的一个对象时,与其关联的其他表的对象也将被一起删除。
第四.实体属性字段
增加字段Entity -> Add Attributes
<1>应该保证实体表中的字段与关联的实体类中字段一致,可以修改一次实体表就重新生成一次实体类,或者修改实体表同时手动修改实体类。
<2>NSManagedObject的字段属性的实现需要使用@dynamic而非@synthsize,不需要系统生成其存取方法,有数据库负责其存取。
属性的类型(type)和(propertites)
第五.其他相关
CoreData简介:
1.应用程序先创建或读取模型文件(后缀为xcdatamodeld)生成 NSManagedObjectModel 对象。Document应用程序是一般是通过 NSDocument 或其子类 NSPersistentDocument)从模型文件(后缀为 xcdatamodeld)读取。
2.然后生成 NSManagedObjectContext 和 NSPersistentStoreCoordinator 对象,前者对用户透明地调用后者对数据文件进行读写。
3.NSPersistentStoreCoordinator 负责从数据文件(xml, sqlite,二进制文件等)中读取数据生成 Managed Object,或保存 Managed Object 写入数据文件。
4.NSManagedObjectContext 参与对数据进行各种操作的整个过程,它持有 Managed Object。我们通过它来监测 Managed Object。监测数据对象有两个作用:支持 undo/redo 以及数据绑定。这个类是最常被用到的。
5.Model类
Model类包含内容:
Entity(实体表),为NSMnanagedObject类或者其子类,抽象数据类型。
Property三种属性:Attribute(用于存储实体表的基本数据),RelationShip(存储关系),FetchedRequest查询条件);
6.ManagedObject类
ManagedObject为Entity的一条记录,每一个ManagedObject被创建时 都有一个全局的NSManagedObjectID,当它别插入到ManagedObjectContext中时,可以通过ID在Context中查询到它。
ManagedOBjectContext管理者对数据对象的每一个操作。
Persistent Store Coordinator用来处理与底层硬件相关的存取操作,一般ManagedObjectContext已经完成了对它的控制和操作,我们无需关心。
FetchRequest
7.FetchRequest与谓词NSPredicate一起作用,用来在NSManagedObjectContext中查询符合条件的实体,结果以NSArray形式给出。通常会见FetchRequest保存以重复利用。
- 本文作者: Grx
- 本文链接: https://ruixiaoguo.github.io/Grx.github.io/Grx.github.io/2015/05/15/创建CoreData基本教程/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!