zoukankan      html  css  js  c++  java
  • iOS开发CoreData的简单使用

    1、简介

      CoreData是iOS5后,苹果提供的原生的用于对象化管理数据并且持久化的框架。iOS10苹果对CoreData进一步进行了封装,而且效率更高!相关类的简单介绍:

    NSManagedObjectModel    模型对象:添加实体的属性,建立属性之间的关系
    NSPersistentStoreCoordinator    数据库的助理:设置数据存储的名字,位置,存储方式,和存储时机
    NSManagedObjectContext  生成上下文,关联数据库助理,插入数据,查询数据,删除数据,更新数据
    NSPersistentContainer (iOS10之后才能使用)一个容器,封装了应用程序中的CoreData Stack(核心数据栈堆)

    2、创建CoreData

      1)创建CoreData操作源文件 xxxx.xcdatamodeld

      方法一:创建工程时直接勾选 Use Core Data 选项

      方法二:手动创建

        通过New File --->>iOS (Core Data) Data Model路径创建!

      2)创建实体(model)

        通过导航栏Editor--->>Create NSManagedObject Subclass--->>选择表 --->> 选择model

     》》》》》》

      然后会生成四个文件如图所示:

      注意:1、右边可以选择创建实体类语言Objective-C或者Swift;

           2、创建之后工程报错CoreData手动创建托管对象子类时报错解决方法;

    3、简单使用CoreData

      方法一:在iOS10之前使用详情

        自动创建CoreData时,在AppDelegate.m文件中有系统封装的方法如下:(手动创建就是把方法复制一遍)

    - (void)applicationWillTerminate:(UIApplication *)application {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        [self saveContext];
    }
    #pragma mark - Core Data stack
    
    //NSManagedObject(被管理的数据记录)
    //数据库中的表格记录
    
    //NSEntityDescription(实体结构)
    //相当于表格结构
    
    //NSFetchRequest(数据请求)
    //相当于查询语句
    
    //.xcdatamodel文件,用数据模型编辑器编辑
    //编译后为.momd或.mom文件
    
    //存储路径
    - (NSURL *)applicationDocumentsDirectory {
        NSLog(@"===%lu",(unsigned long)NSDocumentDirectory);
        return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    }
    
    //创建模型对象
    //作用:添加实体的属性,建立属性之间的关系
    //操作方法:视图编辑器,或代码
    - (NSManagedObjectModel *)managedObjectModel {
        if (_managedObjectModel != nil) {
            return _managedObjectModel;
        }
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataTest" withExtension:@"momd"];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
        return _managedObjectModel;
    }
    
    //创建数据库助理
    //作用:设置数据存储的名字,位置,存储方式,和存储时机
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
        if (_persistentStoreCoordinator != nil) {
            return _persistentStoreCoordinator;
        }
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataTest.sqlite"];
        NSError *error = nil;
        NSString *failureReason = @"There was an error creating or loading the application's saved data.";
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            NSMutableDictionary *dict = [NSMutableDictionary dictionary];
            dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
            dict[NSLocalizedFailureReasonErrorKey] = failureReason;
            dict[NSUnderlyingErrorKey] = error;
            error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
        
        return _persistentStoreCoordinator;
    }
    
    //生成上下文,关联数据库助理
    //作用:插入数据,查询数据,删除数据,更新数据
    - (NSManagedObjectContext *)managedObjectContext {
        if (_managedObjectContext != nil) {
            return _managedObjectContext;
        }
        
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (!coordinator) {
            return nil;
        }
        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        return _managedObjectContext;
    }
    
    #pragma mark - Core Data Saving support
    //保存
    - (void)saveContext {
        NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
        if (managedObjectContext != nil) {
            NSError *error = nil;
            if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
                abort();
            }
        }
    }

        具体的增加、删除、修改、查找数据操作如下:(一般情况下使用CoreData都会自己把上面方法封装,组成一个CoreData的工具类)

    //添加一条数据
    - (void)addData{
        Student *newEintity = [NSEntityDescription insertNewObjectForEntityForName:Model_Name inManagedObjectContext:self.managedObjectContext];
        newEintity.name = @"张三";
        newEintity.age = @"13";
        [self saveContext];
    }
    
    //删除一条数据
    - (void)deleData{
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:Model_Name];
        NSPredicate *predic = [NSPredicate predicateWithFormat:@"name = %@",@"张三"];
        request.predicate = predic;
        NSArray *arr = [self.managedObjectContext executeFetchRequest:request error:nil];
        if (arr.count>0) {
            [self.managedObjectContext deleteObject:arr.firstObject];
            [self saveContext];
        }
    }
    //删除和修改数据时先查找
    //改变一条数据
    - (void)exchangeData{
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:Model_Name];
        NSPredicate *predic = [NSPredicate predicateWithFormat:@"name = %@",@"张三"];
        request.predicate = predic;
        NSArray *arr = [self.managedObjectContext executeFetchRequest:request error:nil];
        if (arr.count>0) {
            Student *objc = (Student *)arr.firstObject;
            objc.name = @"李四";
            objc.age = @"43";
            [self saveContext];
        }
    }

      方法二:iOS10之后,苹果添加了一个NSPersistentContainer类,将之前方法进行了封装。这时候AppDelegate.m中的方法只有:

    - (void)applicationWillTerminate:(UIApplication *)application {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        // Saves changes in the application's managed object context before the application terminates.
        [self saveContext];
    }
    
    
    #pragma mark - Core Data stack
    
    @synthesize persistentContainer = _persistentContainer;
    
    - (NSPersistentContainer *)persistentContainer {
        // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it.
        @synchronized (self) {
            if (_persistentContainer == nil) {
                _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"TestCoreData"];
                [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
                    if (error != nil) {
                        NSLog(@"Unresolved error %@, %@", error, error.userInfo);
                        abort();
                    }
                }];
            }
        }
        return _persistentContainer;
    }
    
    #pragma mark - Core Data Saving support
    
    - (void)saveContext {
        NSManagedObjectContext *context = self.persistentContainer.viewContext;
        NSError *error = nil;
        if ([context hasChanges] && ![context save:&error]) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, error.userInfo);
            abort();
        }
    }

      具体的增加、删除、修改、查找数据操作如下:

    //添加一条数据
    - (void)addData{
        Student *newEintity = [NSEntityDescription insertNewObjectForEntityForName:Model_Name inManagedObjectContext:self.delegate.persistentContainer.viewContext];
        newEintity.name = @"张三";
        newEintity.age = @"13";
        [self.delegate saveContext];
    }
    
    //删除一条数据
    - (void)deleData{
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:Model_Name];
        NSPredicate *predic = [NSPredicate predicateWithFormat:@"name = %@",@"张三"];
        request.predicate = predic;
        NSArray *arr = [self.delegate.persistentContainer.viewContext executeFetchRequest:request error:nil];
        if (arr.count>0) {
            [self.delegate.persistentContainer.viewContext deleteObject:arr.firstObject];
            [self.delegate saveContext];
        }
    }
    //删除和修改数据时先查找
    //改变一条数据
    - (void)exchangeData{
        NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:Model_Name];
        NSPredicate *predic = [NSPredicate predicateWithFormat:@"name = %@",@"张三"];
        request.predicate = predic;
        NSArray *arr = [self.delegate.persistentContainer.viewContext executeFetchRequest:request error:nil];
        if (arr.count>0) {
            Student *objc = (Student *)arr.firstObject;
            objc.name = @"李四";
            objc.age = @"43";
            [self.delegate saveContext];
        }
    }

    4、关于iOS10新类NSPersistentContainer的简介

    //版本要求
    API_AVAILABLE(macosx(10.12),ios(10.0),tvos(10.0),watchos(3.0))
    @interface NSPersistentContainer : NSObject {
    #if (!__OBJC2__)
    //将之前的属性直接封装
    @private
        id _name;
        NSManagedObjectContext *_viewContext;
        id _storeCoordinator;
        id _storeDescriptions;
    #endif
    }
    
    /**类方法创建NSPersistentContainer
    * name:表示保存的数据库文件名称
    * 使用此方法创建NSPersistentContainer,默认模型文件名称为name
    */
    + (instancetype)persistentContainerWithName:(NSString *)name;
    /**类方法创建NSPersistentContainer
    * name:表示保存的数据库文件名称
    * model:对象管理模型
    */
    + (instancetype)persistentContainerWithName:(NSString *)name managedObjectModel:(NSManagedObjectModel *)model;
    
    //返回沙盒中存储数据库的文件夹URL路径,这个文件夹是动态创建的(Library->Application Support)
    + (NSURL *)defaultDirectoryURL;
    
    //当前NSPersistentContainer容器的名称
    @property (copy, readonly) NSString *name;
    //自动生成的管理对象上下文,这个上下文默认的操作类型是NSMainQueueConcurrencyType主线程
    @property (strong, readonly) NSManagedObjectContext *viewContext;
    //对象管理模型
    @property (strong, readonly) NSManagedObjectModel *managedObjectModel;
    //存储调度器
    @property (strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
    //存储器描述数组
    @property (copy) NSArray<NSPersistentStoreDescription *> *persistentStoreDescriptions;
    
    // 和上面初始化一样
    - (instancetype)initWithName:(NSString *)name;
    - (instancetype)initWithName:(NSString *)name managedObjectModel:(NSManagedObjectModel *)model NS_DESIGNATED_INITIALIZER;
    
    //加载存储器,此方法必须要调用,否则无法存储数据
    //block中NSPersistentStoreDescription用于描述生成的存储器信息,如:数据库文件路径、存储类型等  NSError用于描述加载存储器是否成功或失败信息
    - (void)loadPersistentStoresWithCompletionHandler:(void (^)(NSPersistentStoreDescription *, NSError * _Nullable))block;
    
    //返回一个基于多线程的管理对象上下文,我们无需关心多线程的内部实现以及线程安全,由NSPersistentContainer新创建一个
    //调用这个方法之后,对返回的上下文做一些数据的处理都是在子线程中完成的,可以用于处理对数据库进行大量数据操作的场景
    - (NSManagedObjectContext *)newBackgroundContext NS_RETURNS_RETAINED;
    
    //使用存储调度器快速在多线程中操作数据库,效率非常高
    - (void)performBackgroundTask:(void (^)(NSManagedObjectContext *))block;
  • 相关阅读:
    thinkphp3.2升级至thinkphp5.0.24
    matlab从曲线图提取数据
    Pandorabox(Openwrt) 双宽带(WAN) 叠加网络实战
    大数据挖掘复习小记
    j2ee课程设计—基于activiti的请休假系统
    算法与数据结构第八次作业——散列表
    算法与数据结构——AVL树(平衡二叉树)
    算法与数据结构第六、七次作业——树
    算法与数据结构第六次作业——排序
    算法与数据结构——排序
  • 原文地址:https://www.cnblogs.com/xianfeng-zhang/p/8297005.html
Copyright © 2011-2022 走看看