• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Harley
博客园    首页    新随笔    联系   管理    订阅  订阅

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 了,因为它的创建需要用到 managedObjectModel,managedObjectModel 告诉了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

 

 

  

posted @ 2018-01-18 14:31  Harely  阅读(223)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3