【iOS】CoreData详解

作者: 雨声不吃鱼 | 来源:发表于2016-11-18 19:22 被阅读1282次

    什么是CoreData

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

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

    为什么要使用CoreData

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

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

    • 提供了可视化设计

    CoreData框架

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

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

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

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

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

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


    AppDelegate.h
    #import <UIKit/UIKit.h>
    #import <CoreData/CoreData.h>
    
    @interface AppDelegate : UIResponder <UIApplicationDelegate>
    
    @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 <Foundation/Foundation.h>
    #import <CoreData/CoreData.h>
    
    @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
    

    参考文献

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

    相关文章

      网友评论

        本文标题:【iOS】CoreData详解

        本文链接:https://www.haomeiwen.com/subject/hnqspttx.html