OC-CoreData的使用

579 阅读3分钟

铺垫:

CoreData几个类

(1)NSManagedObjectContext

意思是托管对象上下文,数据库的大多数操作是在这个类操作

(2)NSManagedObjectModel

意思是托管对象模型,其中一个托管对象模型关联到一个模型文件,里面存储着数据库的数据结构。

(3)NSPersistentStoreCoordinator

意思是持久化存储协调器,主要负责协调上下文玉存储的区域的关系。

(4)NSManagedObject

意思是托管对象类,其中CoreData里面的托管对象都会继承此类。

image.png

1.创建Person.xcdatamodeld

image.png

image.png

2.准备工具类

HMCoreDataManager.h:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface HMCoreDataManager : NSObject

//创建一个管理对象上下文
@property (nonatomic , strong)NSManagedObjectContext *managerContext;

//简单的单例
+ (instancetype)sharedManager;

@end

HMCoreDataManager.m:

#import "HMCoreDataManager.h"

@implementation HMCoreDataManager

//实现单例

static HMCoreDataManager *sharemanager;

+(instancetype)sharedManager

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharemanager = [HMCoreDataManager new];
    });

    return sharemanager;
}

-(NSManagedObjectContext *)managerContext

{
    if (_managerContext == nil) {
        //创建对象
        _managerContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];

        //给上下文设置持久化存储协调器

        //模型文件的url
        NSURL *url = [[NSBundle mainBundle]URLForResource:@"Person" withExtension:@"momd"];

        //根据url 获取到模型文件
        NSManagedObjectModel *model = [[NSManagedObjectModel alloc]initWithContentsOfURL:url];

        //设置模型文件
        NSPersistentStoreCoordinator *per = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:model];

        //数据路径一般放在沙盒 为了演示才放到电脑桌面
        NSURL *file = [NSURL fileURLWithPath:@"/Users/kaixin/Desktop/person/person.db"];

        //添加数据库文件路径
        [per addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:file options:nil error:nil];

        [_managerContext setPersistentStoreCoordinator:per];
    }

    return _managerContext;
}

3.设置模型

在Person.xcdatamodeld中:

image.png

image.png

image.png

image.png

image.png

4.ViewController.m

#import "ViewController.h"

#import "HMCoreDataManager.h"

#import "Person.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

   //存储数据
    [self saveData];

    //查询数据
    [self fetchData];
}

//存储数据
- (void)saveData
{
    //通过实体描述描述出实体对象
  Person *person =  [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[HMCoreDataManager sharedManager].managerContext];

    //数据存储插入操作  KVC
//    [person setValue:@"leo" forKey:@"name"];
    person.name = @"wwh11111";
    person.age = @(23);

    //通过上下文进行提交存储
    [[HMCoreDataManager sharedManager].managerContext save:nil];
}

//查询数据
- (void)fetchData
{
    //查询请求
    NSFetchRequest *fetchrequest = [[NSFetchRequest alloc]init];

    //设置一些参数
    //实体
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:[HMCoreDataManager sharedManager].managerContext];

    //设置实体
    fetchrequest.entity = entity;

//    //谓词   有点像SQL语句中的 where
//    NSPredicate *pre = [NSPredicate predicateWithFormat:@"age = %@",@"26"];

//    //设置一下
//    fetchrequest.predicate = pre;

    //排序
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];

    //设置排序
    fetchrequest.sortDescriptors = @[sort];

    //执行查询请求

    NSArray *temp = [[HMCoreDataManager sharedManager].managerContext executeFetchRequest:fetchrequest error:nil];

    //打印结果集
    for (Person *person in temp) {
        NSLog(@"%@ 一共有多少个记录%lu",person.name,temp.count);
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

自己踩的坑

  1. 系统会自动生成的文件 实体对象名(就是之前加的ENTITIES)+CoreDataProperties.h:

系统会自动生成属性:

例如:我之前bingXiang属性类型选择了boolean

@property (nonatomic) BOOL bingXiang;

这里有两个坑:

尽量不要用布尔值, 手动更改系统给的属性参数 增加retain

1)关于布尔值:

oomake.com/question/17… (见问题的回答部分)

属性设置:

@property (nonatomic, retain) NSNumber *booleanProperty;

使用:

self.booleanProperty = [NSNumber numberWithBool:YES];

self.booleanProperty.boolValue == YES;

2)关于retain:

先留一个空,我现在还不懂,哪位大神看到了还请留言解答一下,本人无限感激。

  1. 系统会自动生成的文件 实体对象名(就是之前加的ENTITIES)+CoreDataProperties.h:

系统会自动生成该类的 NSFetchRequest(都实体化了)

+ (NSFetchRequest<Livingroom *> *)fetchRequest NS_SWIFT_NAME(fetchRequest());

  1. 如何只创建一次数据库 Kitchen?
//先获取一下
NSArray **temp = [[JFCoreDataManager sharedManager].managerContext executeFetchRequest:[Kitchen fetchRequest] error:nil];
if(temp.count == 0){
//创建数据库
}else{
return;
}
  1. 在使用文件里,比如viewController里面import头文件

这是系统自动生成的:

image.png

在需要用到的文件里面:

#import "Kitchen+CoreDataClass.h"

Kitchen+CoreDataClass.h里面

#import <Foundation/Foundation.h>

#import <CoreData/CoreData.h>

NS_ASSUME_NONNULL_BEGIN

@interface Kitchen : NSManagedObject

@end

NS_ASSUME_NONNULL_END

#import "Kitchen+CoreDataProperties.h"