CoreData

结构图


1.模型文件

1.1 创建模型文件

1.2 创建实体

点击下面的 Add Entity 按钮可以添加一个Entity,也就是一个数据实体,相当于数据库中的一张表

1.3  图中的 Attributes 是定义属性的地方,Relationships 是定义关联关系的地方,点击加号可以添加。下面来给 UserLandlord1.0 添加三个字段: landlordId, landlordPassword,还可以选中一个字段,可以在右侧的面板中对它做一些自定义:

  例如在 validation 里对数据做一些限制,字符串的长度,数字类型的最大最下值;设置索引、默认值等。不同的数据类型可以设置不同的内容,一般维持默认就可以。

  另外对于每一个 entity 实体类,Build 过后 Xcode 都会自动帮我们生成相应的实体类代码,生成的代码不会在工程目录中显示出来,但是可以通过导入头文件索引到;当然也可以配置成手动生成的,选中对应的 Entity 然后点击右侧面板的 Codegen,把 ClassDefinition 修改成 Manual/None,然后 Xcode 就不会再自动生成了。

1.4 另外,Xcode 自动生成的代码都是 Swift 语言的,如果想改成Objc,可以在这里改:

 

注意:下图一定要选这个,否则会报错!

1.5 这个时候也可以通过 Editor -> Create NSManagedObject Subclass 来生成相应的实体类:

 

需要注意的是,如果前面有自动生成过这些类文件,手动生成后可能会编译出错,因为工程里会索引到两份同样的代码,这个时候需要 Clean 一下工程再 Build 即可。

1.6 下面是自动生成的实体类:

 

到此为止,CoreData 的数据模型就创建好了。

2. CoreData 栈的创建

数据模型创建好之后,想要使用 CoreData 进行数据持久化,下一步就是初始化 CoreData 栈了。 

2.1 CoreData 栈是 CoreData 初始化被访问的框架对象的集合,以及应用中数据对象和外部数据存储的媒介。CoreData 的初始化需要一步步地初始化 CoreData 栈上的三个对象结构,它们分别是:

    a. NSManagedObjectModel — 描述了数据模型的结构信息

    b. NSPersistentStoreCoordinator — 数据持久层和内存对象模型的协调器

    c. NSManagedObjectContext — 内存中 managedObject 对象的上下文

2.2 下图是 CoreData 栈的结构

3.用代码实现

 3.1 创建 NSManagedObjectModel 对象,它需要通过上文中讲的数据模型文件来创建

需要导入 “#import <CoreData/CoreData.h>”

1 //    采用懒加载方式,创建管理对象模型
2 - (NSManagedObjectModel *)managedObjectModel{
3     if (_managedObjectModel) {
4 //        url 为ModelLandlord.xcdatamodeld,注意扩展名为 momd,而不是 xcdatamodeld 类型
5         NSURL *modelUrl = [[NSBundle mainBundle] URLForResource:@"ModelLandlord" withExtension:@"momd"];
6         _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl];
7     }
8     return _managedObjectModel;
9 }

3.2 创建 NSPersistentStoreCoordinator

  创建好 managedObjectModel 后就可以来创建 persistentStoreCoordinator 了,因为它的创建需要用到 managedObjectModelmanagedObjectModel 告诉了persistentStoreCoordinator 数据模型的结构,然后 persistentStoreCoordinator 会根据对应的模型结构创建持久化的本地存储。

 1 /* 持久存储调度器 */
 2 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
 3     if (!_persistentStoreCoordinator) {
 4 //        创建 coordinator 需要传入 managedObjectModel
 5         _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
 6 //        指定本地的 sqlite 数据库文件
 7         NSURL *sqliteURL = [[self getDocumentURL] URLByAppendingPathComponent:@"ModelLandlord.sqlite"];
 8         NSError *error;
 9 //        为 persistentStoreCoordinator 指定本地存储的类型,这里指定的是 SQLite
10         [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqliteURL options:nil error:&error];
11         if (error) {
12             NSLog(@"falied to create persistentStoreCoordinator %@", error.localizedDescription);
13         }
14     }
15     return _persistentStoreCoordinator;
16 }
17 
18 #pragma mark *** 获取沙盒路径的URL地址 ***
19 - (NSURL *) getDocumentURL {
20     NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
21     return url;
22 }

3.3 创建 NSManagedObjectContext

创建 managedObjectContext, 这也是平时操作 CoreData 主要会用到的对象

1 - (NSManagedObjectContext *)context {
2     if (!_context) {
3 //        指定 context 的并发类型: NSMainQueueConcurrencyType 或 NSPrivateQueueConcurrencyType
4         _context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
5         _context.persistentStoreCoordinator = self.persistentStoreCoordinator;
6     }
7     return _context;
8 }

 至此,CoreData 栈的初始化就创建完成了。以后操作 CoreData 就可以通过 context 属性来完成,操作完之后调用 context 的 save 方法就可以数据持久化到本地。

1 func performBlock(_ block: () -> Void)//在私有队列中异步地执行 Blcok 
2  func performBlockAndWait(_ block: () -> Void)//在私有队列中执行 Block 直至操作结束才返回 

4. 增、删、查、改

4.1 添加数据

 1 - (void)testAddData {
 2 //    根据Entity名称和NSManagedObjectContext获取一个新的继承于NSManagedObject的子类Student
 3     NSLog(@"--------->%@",self.context);
 4     Landlord *landlord = [NSEntityDescription insertNewObjectForEntityForName:@"Landlord" inManagedObjectContext:self.context];
 5     
 6 //    根据表Landlord中的键值,给NSManagedObject对象赋值
 7     landlord.landlordId = @"111111";
 8     landlord.landlordPassword = @"password";
 9     
10 //    保存数据
11     NSError *error = nil;
12     if ([self.context save:&error]) {
13         NSLog(@"插入数据成功!");
14     }else {
15         NSLog(@"数据插入到数据库失败, %@",error);
16     }
17     
18 }

4.2 读取数据

 1 - (void)testReadData {
 2 //    创建查询请求
 3     NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Landlord"];
 4 //    查询条件
 5     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"landlordPassword = %@",@"password"];
 6     request.predicate = predicate;
 7     
 8 //    从第几页开始显示
 9 //    通过这个属性实现分页
10     request.fetchOffset = 0;
11 //    每页显示多少条数据
12     request.fetchLimit = 6;
13     
14 //    发送查询请求
15     NSArray *resArray = [self.context executeFetchRequest:request error:nil];
16     NSLog(@"查询的数据是:%@",[resArray.firstObject landlordId]);
17 }

4.3 更新数据

 1 - (void)testUpdateData {
 2 //    创建查询请求
 3     NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Landlord"];
 4     NSPredicate *pre = [NSPredicate predicateWithFormat:@"landlordPassword = %@", @"password"];
 5     request.predicate = pre;
 6     
 7 //    发送请求
 8     NSArray *resArray = [self.context executeFetchRequest:request error:nil];
 9 //    修改
10     for (Landlord *lan in resArray) {
11         lan.landlordId = @"且行且珍惜_iOS";
12     }
13     
14 //    保存
15     NSError *error = nil;
16     if ([self.context save:&error]) {
17         NSLog(@"更新所有帅哥的的名字为“且行且珍惜_iOS");
18     }else{
19         NSLog(@"更新数据失败, %@", error);
20     }
21     
22 }

4.4 删除数据

 1 - (void)testDeleteData {
 2 //    创建删除请求
 3     NSFetchRequest *deleRequest = [NSFetchRequest fetchRequestWithEntityName:@"Landlord"];
 4     
 5 //    删除条件
 6     NSPredicate *pre = [NSPredicate predicateWithFormat:@"landlordPassword = %@", @"password"];
 7     deleRequest.predicate = pre;
 8     
 9 //    返回需要删除的对象数组
10     NSArray *deleArray = [self.context executeFetchRequest:deleRequest error:nil];
11     
12 //    从数据库中删除
13     for (Landlord *stu in deleArray) {
14         [self.context deleteObject:stu];
15     }
16     
17     NSError *error = nil;
18     //保存--记住保存
19     if ([_context save:&error]) {
20        NSLog(@"删除 age < 10 的数据");
21     }else{
22         NSLog(@"删除数据失败, %@", error);
23     }
24     
25     
26 }

 4.5 排序

 1 - (void)sort{
 2     //创建排序请求
 3     NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Landlord"];
 4     //实例化排序对象
 5     NSSortDescriptor *landlordId = [NSSortDescriptor sortDescriptorWithKey:@"landlordId"ascending:YES];
 6     request.sortDescriptors = @[landlordId];
 7     //发送请求
 8     NSError *error = nil;
 9     NSArray *resArray = [self.context executeFetchRequest:request error:&error];
10     if (error == nil) {
11         [self alertViewWithMessage:@"按照age和number排序"];
12     }else{
13         NSLog(@"排序失败, %@", error);
14     }
15 }

 5. CoreData 的调试

选择【Product】【scheme】【Edit scheme】 

选择【Arguments】,在【ArgumentsPassed On Launch】添加两个选项:

(1)-com.apple.CoreData.SQLDebug
(2)1

  

原文地址:https://www.cnblogs.com/EchoHG/p/8310077.html