【iOS】CoreData详解

什么是CoreData

  • CoreData 不是一个数据库但是可以使用数据库来存储数据,也可以使用其他方式,比如:数据库文件,XML,二进制文件,内存等。CoreData 提供了 对象-关系映射(ORM) 功能。能够实现数据库数据和 OC 对象的相互转换,在这个转换过程中我们不需要编写任何 SQL 语句。

  • 可以简单的理解为Cocoa对SQLite的一层封装

为什么要使用CoreData

  • 极大的减少Model层的代码量

  • 优化了使用SQLite时候的性能

  • 提供了可视化设计

CoreData框架

【iOS】CoreData详解_第1张图片
CoreData

  • .xcdatamodeld 文件:定义了数据库数据和 OC 对象转换的映射关系,编译后为 .momod 文件

  • NSManagedObjectModel:负责读取解析 .momod 文件

  • NSPersistentStoreCoordinator:通过解析结果去实现数据库和 OC 对象之间的相互转换,主要是操作数据库的,我们一般用不上,由系统处理

  • NSManagedObjectContext:等同于一个容器,用来存储从数据库中转换出来的所有的 OC 对象。我们的增删改查操作直接对这个类使用来获得或者修改需要的 OC 对象,它能够调用 NSPersistentStoreCoordinator 类实现对数据库的同步

  • NSManagedObject:数据库中的数据转换而来的OC对象

*注:
1. 一旦数据创建完毕,就不能再修改.xcdatamodeld文件,如果有修改,必须删除数据库重新创建,否则打开数据库已定会失败。 去沙盒路径下把创建的数据库删除即可
2. 不能使用alloc init来创建对象


AppDelegate.h
#import 
#import 

@interface AppDelegate : UIResponder 

@property (strong, nonatomic) UIWindow * window;

/**
  * 上下文  容器  
  * 存放的是 所有从数据库中取出的转换成OC对象
  */
@property (readonly, strong, nonatomic) NSManagedObjectContext * managedObjectContext;

/* 读取解析 .momd文件中的内容 */
@property (readonly, strong, nonatomic) NSManagedObjectModel * managedObjectModel;

/* 连接的类,处理数据库数据和OC数据底层的相互转换 */
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator * persistentStoreCoordinator;

/* 保存 */
-(void)saveContext;

/* 获取沙盒路径 */
-(NSURL *)applicationDocumentsDirectory;

@end
AppDelegate.m
#import "AppDelegate.h"
#import "People.h"

@interface AppDelegate ()
@end

@implementation AppDelegate

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"沙盒路径路径:%@",[self applicationDocumentsDirectory].absoluteString);
    
    NSLog(@"%@",self.managedObjectContext);

    
    //插入一条数据 (往People表中插入一条数据)
    //NSEntityDescription 实体类
    //EntityForName 实体名称(表名)
    People * p = [NSEntityDescription insertNewObjectForEntityForName:@"People" inManagedObjectContext:self.managedObjectContext];
    //赋值
    p.name = @"李四";
    p.age = @(25);
    p.phone = @"13667895678";
    //同步操作  把context中的数据同步到数据库中
    [self saveContext];
    
    
    
    // 查询数据
    // 创建查询请求
    NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    // Context 执行请求(执行查询操作) 数组中存放的是oc类的对象(People类的对象)
    NSArray * array = [self.managedObjectContext executeFetchRequest:request error:nil];
    for (People *people in array)
    {
       NSLog(@"%@",people.name);
    }
    
    
    //查询特定条件数据  (年龄>20)
    NSFetchRequest * request1 = [NSFetchRequest fetchRequestWithEntityName:@"People"];
    //使用谓词指定查询的判定条件
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"SELF.age > 20"];
    //关联判定条件
    [request1 setPredicate:predicate];
    //执行查询操作
    NSArray * array2 = [self.managedObjectContext executeFetchRequest:request1 error:nil];
    for (People * people in array2)
    {
        NSLog(@"%@",people.age);
    }
    
    

    //更改数据
    //获取出要修改的数据
    People * people2 = [array lastObject];
    //修改属性
    people2.name = @"123";
    people2.age  = @(30);
    //同步数据
    [self saveContext];
    


    //删除数据
    People * people3 = [array lastObject];
    [self.managedObjectContext deleteObject:people3];
    //同步数据
    [self saveContext];
    
    return YES;
}

//点击HOME键程序直接退出
-(void)applicationWillTerminate:(UIApplication *)application
{
    [self saveContext];
}

#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

-(NSURL *)applicationDocumentsDirectory
{
    //获取沙盒路径下documents文件夹的路径 NSURL   (类似于search)
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

//managedObjectModel 属性的getter方法
-(NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) return _managedObjectModel;

    //.xcdatamodeld文件 编译之后变成.momd文件  (.mom文件)
    NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData_Class" withExtension:@"momd"];
    
    //把文件的内容读取到managedObjectModel中
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
    return _managedObjectModel;
}

//Coordinator 调度者负责数据库的操作 创建数据库 打开数据 增删改查数据
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;

    //根据model创建了persistentStoreCoordinator
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    
    // 设置数据库存放的路径
    NSURL * storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData_Class.sqlite"];
    
    NSError * error = nil;
    
    //如果没有得到数据库,程序崩溃
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
    {
        NSLog(@"错误信息: %@, %@", error, [error userInfo]);
        abort(); //崩溃
    }
    
    return _persistentStoreCoordinator;
}

//容器类 存放OC的对象
-(NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil)  return _managedObjectContext;
    
    NSPersistentStoreCoordinator * coordinator = [self persistentStoreCoordinator];
    if (!coordinator)
    {
        return nil;
    }
    
    //创建context对象
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    
    //让context和coordinator关联   context可以对数据进行增删改查功能
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

-(void)saveContext
{
    NSManagedObjectContext * managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil)
    {
        NSError * error = nil;

        // hasChanges 判断数据是否更改
        // sava 同步数据库中的数据
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
        {
            NSLog(@"错误信息: %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

@end
People.h
#import 
#import 

@interface People : NSManagedObject

@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * phone;

@end
People.m
#import "People.h"

@implementation People

/**
 * @property    描述对应@synthesize和@synamic两个关键字
 * @synthesize  会生成属性的setter,getter方法
 * @dynamic     不生成属性的setter,getter方法
 * 两个都没有写,默认是@synthesize
 */

@dynamic age;
@dynamic name;
@dynamic phone;

@end

参考文献

  • iOS CoreData介绍和使用
  • 关于CoreData的增 删 改

微信公共号:iapp666666
GitHub:点此前往

你可能感兴趣的:(【iOS】CoreData详解)