iOS学习笔记-CoreData

简介

  CoreData提供了对象关系映射(ORM)功能,从效果上说就是创建了一个"虚拟对象数据库",也可以把它看作一个综合的数据库管理库。

NSManagedObjectContext

  被管理的数据上下文对象,主要负责应用和数据库之间的交互。我们就是用它来进行增删改查操作。它会记录用户对数据的所有改变。它有NSPersistentStoreCoordinator

属性。创建它需要设置NSPersistentStoreCoordinator。

NSPersistentStoreCoordinator

  持久化数据协调库,用于添加持久化存储库,相当于数据库的连接器。也就是我们用数据库做持久化还是用XML做持久化是由它决定的。我们用它来设置存储库的类型和指定存储库的路径。它有NSManagedObjectModel属性。

NSManagedObjectModel

  NSManagedObjectModel代表CoreData的模型文件。CoreData项目中有一个.xcdatamodeld文件,它就是CoreData的模型文件。我们在.xcdatamodeld文件里进行创建实体和添加实体的属性。所以所有的实体信息都在NSManagedObjectModel中。

NSManagedObject

  NSManagedObject对应实体,NSManagedObject是实体的映射,被CoreData管理的数据记录。也就是说在CoreData中我们直接操作的数据对象是NSManagedObject,你可以把它们当做一个东西,但是在代码中我们使用NSManagedObject。

NSEntityDescripition

  实体描述类。包含实体的名字和属性。可以通过它来操作指定的实体。

基于SQLite简单使用

1.创建工程

若是新建的工程,勾选Use Core Data选项

    

AppDelegate文件中自动生成被管理数据上下文等相关代码,不用我们自己来进行相关的配置,可以直接使用。

在AppDelegate.h文件中添加如下代码:

/**
 *  上下文对象,负责应用和数据库之间的交互。我们就是用它来操作实体,进行增删改查等操作
 */
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
/**
 *  管理数据模型,代表CoreData的模型文件。包含了所有实体的信息。
 */
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
/**
 *  持久性数据协调器,添加持久化存储裤。在这里设置使用数据库还是xml等存储裤来做持久化,以及存储裤的路径
 */
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
//保存数据到持久层(数据库)
- (void)saveContext;
//应用程序沙盒Document目录
- (NSURL *)applicationDocumentsDirectory;

在AppDelegate.m文件中:

保存数据到持久层

- (void)applicationWillTerminate:(UIApplication *)application {
    [self saveContext];
}

- (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();
        }
    }
}

被管理的数据模型

- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    //指定.xcdatamodeld文件,该文件编译后会变为momd文件
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataDemo" 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:@"CoreDataDemo.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application‘s saved data.";

    /*
     addPersistentStoreWithType:指定存储类型
     NSSQLiteStoreType: 数据库
     NSXMLStoreType: XML
     NSBinaryStoreType: 二进制文件
     NSInMemoryStoreType: 内存形式
     */
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        // Report any error we got.
        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;
}

如果不是新工程建模后加入这些代码即可

2.添加实体

在工程中选中.xcdatamdeld文件

点击

在右侧栏对实体命名

或者双击默认实体名进行命名

点击Add Attribute添加实体属性

如果一个实体中包含另一个实体,例如有一个实体Person还有一个实体Card。Person中有一个属性card,Card中也有一个属性person。那么就需要建立两个实体间的关系。如果下图这个页面,点击上图的Editor Style按钮切换一下。

两个实体都按这种方法创建关系。

选中关系,在右侧Delete Rule可以设置删除规则

关联模式Cascade,一个数据被删除,另一个实体的数据也会删除。

按Editor Style按钮切换到另一种视图模式,最终两个实体关系图为:

3.为每个实体生成NSManagedObject子类

具体的类名就是实体的class,默认情况下就是实体的名字。如果不想用实体名字做类名只需更改实体的class:

4.插入数据

AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    //获取上下文
    NSManagedObjectContext *contxt = [appDelegate managedObjectContext];

    //创建Person对象。创建被管理的NSManagedObject对象,指定实体名字
    Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:contxt];
    //设置person属性
    [person setValue:@"小小" forKey:@"name"];
    [person setValue:[NSNumber numberWithInt:29] forKey:@"age"];

    //创建Card对象。
    Card *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:contxt];
    //设置card属性
    [card setValue:[NSNumber numberWithInt:130] forKey:@"num"];

    //设置对象间关系
    [person setValue:card forKey:@"card"];
    [card setValue:person forKey:@"person"];

    NSError *error = nil;
    /*
     hasChanges:判断数据是否有变化
     save:保存数据变化,并将其同步到持久化数据文件中
     */
    if ([contxt hasChanges] && ![contxt save:&error]) {
        NSLog(@"插入失败:%@,%@",error,error.userInfo);
    }
    else {
        NSLog(@"插入成功");
    }

5.查询数据

    AppDelegate *appDelegate = [[AppDelegate alloc] init];
    NSManagedObjectContext *cxt = [appDelegate managedObjectContext];

    //实体关联的描述类,指定实体名字获取
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:cxt];

    //数据提取请求类
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    //实体描述设定到请求对象中
    fetchRequest.entity = entity;
    //查询条件,如果想查询全部补设置查询条件即可
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"小明"];
    //排序,指定排序字段和排序方式。根据年龄正序排序
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
    //把排序描述设定到请求对象中
    NSArray *sortDescriptors = @[sortDescriptor];
    fetchRequest.sortDescriptors = sortDescriptors;
    //限制一次提取数据的纪录数
    fetchRequest.fetchLimit = 10;

    NSError *error = nil;
    //请求查询,返回数组中存放被管理的ModelManagedObject实体对象
    NSArray *listData = [cxt executeFetchRequest:fetchRequest error:&error];
    for (Person *person in dataList) {
         NSLog(@"\nname:%@\tage:%@\ncard:%@",person.name,person.age,person.card.num);
    }

6.删除数据

    AppDelegate *appDelegate = [[AppDelegate alloc] init];
    NSManagedObjectContext *cxt = appDelegate.managedObjectContext;

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Model" inManagedObjectContext:cxt];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = entity;
    request.predicate = [NSPredicate predicateWithFormat:@"title=%@",model.title];

    NSError *error = nil;
    NSArray *listData = [cxt executeFetchRequest:request error:&error];

    if (listData.count > 0) {
        ModelManagedObject *modelObject = [listData lastObject];
        [cxt deleteObject:modelObject];

        error = nil;
        if ([cxt hasChanges] && ![cxt save:&error]) {
            NSLog(@"删除数据失败:%@",[error userInfo]);
        }
        else {
            NSLog(@"删除数据成功");
        }
    }

7.修改数据

    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *contxt = [appDelegate managedObjectContext];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:contxt];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    fetchRequest.entity = entity;

    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"小明"];
    NSArray *dataList = [contxt executeFetchRequest:fetchRequest error:nil];

    Person *p = dataList.lastObject;
    p.name = @"小红";

    if ([contxt hasChanges] && ![contxt save:nil]) {
        NSLog(@"修改失败");
    }
    else {
        NSLog(@"修改成功");
    }
时间: 2024-10-17 04:48:34

iOS学习笔记-CoreData的相关文章

iOS学习笔记之UITableViewController&UITableView

iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论文,因此需要继续思考新的算法.这是一件挺痛苦的事情,特别是在很难找到与自己研究方向相关的文献的时候.也许网格序列水印这个课题本身的研究意义就是有待考证的.尽管如此,还是要努力的思考下去.由于实验室的原因,iOS的学习进度明显受到影响,加之整理文档本身是一件耗费时间和精力的事情,因此才这么久没有写笔记了. M

iOS: 学习笔记, Swift操作符定义

Swift操作符可以自行定义, 只需要加上简单的标志符即可. @infix 中置运算. 如+,-,*,/运算 @prefix 前置运算. 如- @postfix 后置运算. a++, a-- @assignment 赋值运算. +=, -=, --a, ++a // // main.swift // SwiftBasic // // Created by yao_yu on 14-7-27. // Copyright (c) 2014年 yao_yu. All rights reserved.

IOS学习笔记 -- Modal和Quartz2D

一. Modal1.Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止;Modal只是改变了View的现实,没有改变rootViewController 2.常用方法1>.以Modal的形式展示控制器- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion2>.关

iOS: 学习笔记, 添加一个带界面约束的控制器

1. 创建一个空iOS应用程序(Empty Application). 2. 添加加控制器类. 修改控制器类的viewDidLoad 1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 //创建标题 5 UILabel *header = [[UILabel alloc] init]; 6 header.text = @"欢迎来到我的世界!"; 7 header.textAlignment = NSTextAlignmentCenter

iOS学习笔记(2)— UIView用户事件响应

iOS学习笔记(2)— UIView用户事件响应 UIView除了负责展示内容给用户外还负责响应用户事件.本章主要介绍UIView用户交互相关的属性和方法. 1.交互相关的属性 userInteractionEnabled 默认是YES ,如果设置为NO则不响应用户事件,并且把当前控件从事件队列中删除.也就是说设置了userInterfaceEnabled属性的视图会打断响应者链导致该view的subview都无法响应事件. multipleTouchEnabled  默认是NO,如果设置为YE

iOS学习笔记(3)— 屏幕旋转

iOS学习笔记(3)— 屏幕旋转 一.屏幕旋转机制: iOS通过加速计判断当前的设备方向和屏幕旋转.当加速计检测到方向变化的时候,屏幕旋转的流程如下: 1.设备旋转时,系统接收到旋转事件. 2.系统将旋转事件通过AppDelegate通知当前的主Window. 3.window通知它的rootViewController. 4.rootViewController判断所支持的旋转方向,完成旋转. iOS系统中屏幕旋转事件没有像触碰事件那样进行hitTest,所以只有rootViewControl

iOS学习笔记(1)— UIView 渲染和内容管理

iOS学习笔记(1)— UIView 渲染和内容管理 iOS中应用程序基本上都是基于MVC模式开发的.UIView就是模型-视图-控制器中的视图,在iOS终端上看到的.摸到的都是UIView. UIView在屏幕上定义了一个矩形区域和管理区域内容的接口.在运行时,一个视图对象控制该区域的渲染:UIView继承自UIResponder,UIResponder是用来响应事件的类,UIView也具有响应事件的能力.所以说UIView具有三个基本的功能,绘制内容并管理内容的布局,响应用户交互,动画.正是

iOS学习笔记-精华整理

iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始等待用户的操作,自动释放池就会被释放掉(调用dealloc),池中的对象都会收到一个release,有可能会因此被销毁. 2-成员属性:     readonly:不指定readonly,默认合成getter和setter方法.外界毫不关心的成员,则不要设置任何属性,这样封装能增加代码的独立性和安全

ios学习笔记图片+图片解释(c语言 oc语言 ios控件 ios小项目 ios小功能 swift都有而且笔记完整喔)

下面是目录其中ios文件夹包括了大部分ios控件的介绍和演示,swift的时完整版,可以学习完swift(这个看的是swift刚出来一周的视频截图,可能有点赶,但是完整),c语言和oc语言的也可以完整的学习完所需知识,,其他文件夹的内容如其名说描述一样 没张图片都有文字说明,可以需要该功能的时候搜索一下然后打开图片就可以学习到 网盘下载地址:需要的话给留言我再传上去 http://www.cnblogs.com/langtianya原创 ios学习笔记图片+图片解释(c语言 oc语言 ios控件

IOS学习笔记-- SQLite的应用

1 // 2 // HMViewController.m 3 // 02-SQLite的应用 4 // 5 // Created by apple on 14-7-24. 6 // Copyright (c) 2014年 heima. All rights reserved. 7 // 8 9 #import "HMViewController.h" 10 #import <sqlite3.h> 11 12 @interface HMViewController () 13