** 使用 Coredata 工程中的 DataModel 创建: 系统创建, 手动创建 **
** 使用 Coredata 需要要导入 < CoreData/CoreData.h> **
1, 系统创建 (系统创建生成 NSPersistentContainer, iOS10+,iPhoneX;iOS8+ 使用手动创建 Coredata)
1.1 创建工程
1.2 创建实体对象
1.3 实体对象命名, Language 属性值选择
1.4 实体对象属性 codegen 选择
1.5 添加实体对象属性
1.6 创建实体对象的子类文件
1.7 创建 NSManagedObject 模型 (模型命名不可和实体名称相同)
1.8 为模型添加属性
- 1.9 Viewcontroller.m (由于系统创建 datamodel, 系统已将 coredata 数据库初始化, 无需自己初始化数据库)
- //
- // ViewController.m
- // Coredatanpp
- //
- // Created by Z_小圣 on 2019/3/19.
- // Copyright © 2019 年 奶瓶瓶. All rights reserved.
- //
- #import "ViewController.h"
- #import "BabyModal.h"
- #import "AppDelegate.h"
- @interface ViewController ()
- {
- NSManagedObjectContext *_context;
- NSPersistentContainer *_container;
- NSManagedObjectModel *_managedObjectModel;
- }
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
- _container = appDelegate.persistentContainer;
- // 返回沙盒中存储数据库的文件夹 URL 路径, 这是一个静态方法, 表示数据库的文件路径是唯一的
- NSURL * url = [NSPersistentContainer defaultDirectoryURL];
- NSLog(@"沙盒路径 %@",url);
- _context = _container.viewContext;
- _managedObjectModel = _container.managedObjectModel;
- // Do any additional setup after loading the view, typically from a nib.
- }
- // 添加方法
- - (IBAction)addAction:(UIButton *)sender {
- // 1. 创建一个新的继承于 NSManagedObject 的子类 BabyModal
- BabyModal *baby = [NSEntityDescription insertNewObjectForEntityForName:@"Baby" inManagedObjectContext:_context];
- //2. 根据表 Baby 中的键值, 给 NSManagedObject 对象赋值
- baby.name = [NSString stringWithFormat:@"长江 -%d",arc4random()%100];
- baby.age = arc4random()%20;
- baby.gender = arc4random()%2 == 0 ? 0: 1;
- // 3. 保存插入的数据
- NSError *error = nil;
- if ([_context save:&error]) {
- NSLog(@"数据插入到数据库成功");
- }else{
- NSLog(@"数据插入到数据库失败,%@",error);
- }
- }
- // 查询方法
- - (IBAction)queryAction:(UIButton *)sender {
- // 创建查询请求
- NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Baby"];
- // 查询条件
- NSPredicate *pre = [NSPredicate predicateWithFormat:@"gender = %@", @"0"];
- request.predicate = pre;
- // 从第几页开始显示
- // 通过这个属性实现分页
- //request.fetchOffset = 0;
- // 每页显示多少条数据
- //request.fetchLimit = 6;
- // 发送查询请求
- NSArray *resArray = [_context executeFetchRequest:request error:nil];
- // 打印查询数据
- for (BabyModal *modal in resArray ) {
- NSLog(@"查询结果: 姓名 =%@ , 年龄 =%ld , 性别 =%@",modal.name,modal.age,[NSString stringWithFormat:@"%d",modal.gender]);
- }
- }
- // 删除方法
- - (IBAction)deleteAction:(UIButton *)sender {
- // 创建删除请求
- NSFetchRequest *deleRequest = [NSFetchRequest fetchRequestWithEntityName:@"Baby"];
- // 删除条件
- NSPredicate *pre = [NSPredicate predicateWithFormat:@"age < %d", 10];
- deleRequest.predicate = pre;
- // 返回需要删除的对象数组
- NSArray *deleArray = [_context executeFetchRequest:deleRequest error:nil];
- // 从数据库中删除
- for (BabyModal *stu in deleArray) {
- [_context deleteObject:stu];
- }
- NSError *error = nil;
- // 保存 -- 记住保存
- if ([_context save:&error]) {
- NSLog(@"删除 age < 10 的数据");
- }else{
- NSLog(@"删除数据失败, %@", error);
- }
- }
- @end
2. 手动创建 (iOS8+ 推荐使用)
2.1 创建工程
2.2 创建 DataModel
2.3 创建实体对象
2.4 实体对象命名, Language 属性值选择
2.5 实体对象属性 codegen 选择
2.6 添加实体对象属性
2.7 创建实体对象的子类文件
2.8 创建 NSManagedObject 模型 (模型命名不可和实体名称相同)
2.9 为模型添加属性
- 2.10 ViewController.m (URLForResource 参数需要根据创建的 Datamodel 的名称来)
- //
- // ViewController.m
- // Coredatanpp
- //
- // Created by Z_小圣 on 2019/3/19.
- // Copyright © 2019 年 奶瓶瓶. All rights reserved.
- //
- #import "ViewController.h"
- #import "BabyModal.h"
- @interface ViewController ()
- {
- NSManagedObjectContext *_context;
- }
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- [self createSqlite];// 创建数据库
- // Do any additional setup after loading the view, typically from a nib.
- }
- // 创建数据库
- - (void)createSqlite{
- //1, 创建模型对象
- // 获取模型路径 URLForResource 参数需要根据创建的 Datamodel 的名称来
- NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoredatanppManual" withExtension:@"momd"];
- // 根据模型文件创建模型对象
- NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
- //2, 创建持久化存储助理: 数据库
- // 利用模型对象创建助理对象
- NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
- // 数据库的名称和路径
- NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
- NSString *sqlPath = [docStr stringByAppendingPathComponent:@"coreData.sqlite"];
- NSLog(@"数据库 path = %@", sqlPath);
- NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath];
- NSError *error = nil;
- // 设置数据库相关信息 添加一个持久化存储库并设置类型和路径, NSSQLiteStoreType:SQLite 作为存储库
- [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlUrl options:nil error:&error];
- if (error) {
- NSLog(@"添加数据库失败:%@",error);
- } else {
- NSLog(@"添加数据库成功");
- }
- //3, 创建上下文 保存信息 对数据库进行操作
- NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
- // 关联持久化助理
- context.persistentStoreCoordinator = store;
- _context = context;
- }
- // 添加方法
- - (IBAction)addAction:(UIButton *)sender {
- // 1. 创建一个新的继承于 NSManagedObject 的子类 BabyModal
- BabyModal *baby = [NSEntityDescription insertNewObjectForEntityForName:@"Baby" inManagedObjectContext:_context];
- //2. 根据表 Baby 中的键值, 给 NSManagedObject 对象赋值
- baby.name = [NSString stringWithFormat:@"长江 -%d",arc4random()%100];
- baby.age = arc4random()%20;
- baby.gender = arc4random()%2 == 0 ? 0: 1;
- // 3. 保存插入的数据
- NSError *error = nil;
- if ([_context save:&error]) {
- NSLog(@"数据插入到数据库成功");
- }else{
- NSLog(@"数据插入到数据库失败,%@",error);
- }
- }
- // 查询方法
- - (IBAction)queryAction:(UIButton *)sender {
- // 创建查询请求
- NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Baby"];
- // 查询条件
- NSPredicate *pre = [NSPredicate predicateWithFormat:@"gender = %@", @"0"];
- request.predicate = pre;
- // 从第几页开始显示
- // 通过这个属性实现分页
- //request.fetchOffset = 0;
- // 每页显示多少条数据
- //request.fetchLimit = 6;
- // 发送查询请求
- NSArray *resArray = [_context executeFetchRequest:request error:nil];
- // 打印查询数据
- for (BabyModal *modal in resArray ) {
- NSLog(@"查询结果: 姓名 =%@ , 年龄 =%ld , 性别 =%@",modal.name,modal.age,[NSString stringWithFormat:@"%d",modal.gender]);
- }
- }
- // 删除方法
- - (IBAction)deleteAction:(UIButton *)sender {
- // 创建删除请求
- NSFetchRequest *deleRequest = [NSFetchRequest fetchRequestWithEntityName:@"Baby"];
- // 删除条件
- NSPredicate *pre = [NSPredicate predicateWithFormat:@"age < %d", 10];
- deleRequest.predicate = pre;
- // 返回需要删除的对象数组
- NSArray *deleArray = [_context executeFetchRequest:deleRequest error:nil];
- // 从数据库中删除
- for (BabyModal *stu in deleArray) {
- [_context deleteObject:stu];
- }
- NSError *error = nil;
- // 保存 -- 记住保存
- if ([_context save:&error]) {
- NSLog(@"删除 age < 10 的数据");
- }else{
- NSLog(@"删除数据失败, %@", error);
- }
- }
- @end
3. 实施中遇到问题
3.1 错误信息:
- :-1:Multiple commands produce '/Users/z_xiaosheng/Library/Developer/Xcode/DerivedData/TeacherCoredata-gmqlwsropogypygztobrkbxffcqs/Build/Intermediates.noindex/TeacherCoredata.build/Debug-iphonesimulator/TeacherCoredata.build/Objects-normal/x86_64/Coreteacheppp+CoreDataProperties.o':
- 1) Target 'TeacherCoredata' (project 'TeacherCoredata') has compile command with input '/Users/z_xiaosheng/Desktop/test/TeacherCoredata/Coreteacheppp+CoreDataProperties.m'
- 2) Target 'TeacherCoredata' (project 'TeacherCoredata') has compile command with input '/Users/z_xiaosheng/Library/Developer/Xcode/DerivedData/TeacherCoredata-gmqlwsropogypygztobrkbxffcqs/Build/Intermediates.noindex/TeacherCoredata.build/Debug-iphonesimulator/TeacherCoredata.build/DerivedSources/CoreDataGenerated/TeacherCoredata/Coreteacheppp+CoreDataProperties.m'
错误原因: 实体属性 Codegen(编译, 生成) 值为非 Manual/None, 创建出来的类编译后会报错.
解决方案: 选中实体将实体属性 Codegen(编译, 生成) 值改为 Manual/None, 清空当前 build, 重新编译
来源: https://www.cnblogs.com/zxs-19920314/p/10577193.html