iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解

cocoa认知

  • Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。

  • CoreData本质是一个ORM框架 ORM Objective-Relational Mapping 这个映射就是我们的模型文件,一般ORM框架都用XML格式来映射 实体Entity+属性数据库表

  • 托管对象(entity) —既不是单纯 内存对象,也不是数据库中的具体的数据,它介于这两个状态之间的,我们叫他游离态的数据

  • CoreData 不能执行SQL语句 取而代之,操作的是对象, FMDB SQLite 可以直接SQL语句

coredata中的核心对象

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第1张图片

在上图中,我们可以看到有五个相关模块:

1, Managed Object Model
Managed Object Model 是 述应用程序的数据模型,这个模型包含实体(Entity),特性(Property),读取请求(Fetch Request) 等。(下文都使用英文术语。)

2,Managed Object Context
Managed Object Context 参与对数据对象进行各种操作的全过程,并监测数据对象的变化,以 供对 undo/redo 的支持及更新绑定到数据的 UI。

3,Persistent Store Coordinator
Persistent Store Coordinator 相当于数据文件管理器,处理底层的对数据文件的读取与写入。一般我们无需与它打交道。

4,Managed Object
Managed Object 数据对象,与 Managed Object Context 相关联。

CoreData的4个存储方式:

  • SQLite NSSQLiteStoreType
  • XML NSXMLStoreType
  • Binary NSBinaryStoreType
  • 内存存储 NSInMemoryStoreType

coredata结构解析

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第2张图片

NSManagedObjectModel

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第3张图片

  • Entity - NSEntityDescription
    Entity 相当于数据库中的一个表,它 述一种抽象数据类型,其对应的类为 NSManagedObject 或其子类。

NSEntityDescription 常用方法:

+insertNewObjectForEntityForName:inManagedObjectContext: 工厂方法,根据给定的 Entity  述,生成相应的 NSManagedObject 对象,并插入 ManagedObjectContext 中。

-managedObjectClassName 返回映射到 EntityNSManagedObject 类名

-attributesByName 以名字为 key, 返回 Entity 中对应的 Attributes

-relationshipsByName 以名字为 key, 返回 Entity 中对应的 Relationships
  • Property - NSPropertyDescription

Property 为 Entity 的特性,它相当于数据库表中的一列,或者 XML 文件中的 value-key 对中的 key。它可以 述实体数据 (Attribute),Entity 之间的关系(RelationShip),或查询属性(Fetched Property)。

Attribute - NSAttributeDescription
Attribute 存储基本数据,如 NSString, NSNumber or NSDate 等。它可以有默认值,也可以使用正则表达式或其他条件对其值 进行限定。一个属性可以是 optional 的。

Relationship - NSRelationshipDescription
Relationship 述 Entity,Property 之间的关系,可以是一对一,也可以是一对多的关系。

Fetched Property - NSFetchedPropertyDescription
Fetched Property 根据查询谓词返回指定 Entity 的符合条件的数据对象。

NSManagedObject – Person

Managed Object 表示数据文件中的一条记录,每一个 Managed Object 在内存中对应 Entity 的一个数据表示。Managed Object 的成员为 Entity 的 Property 所 述。

比如在上面的代码,person 这个 NSManagedObject,对应名为 Person 的 Entity。

每一个 Managed Object 都有一个全局 ID(类型为:NSManagedObjectID)。Managed Object 会附加到一个 Managed Object Context,我们可以通过这个全局 ID 在 Managed Object Context 查询对应的 Managed Object。

这里写图片描述
这里写图片描述

NSManagedObjectContext

Managed Object Context 的作用相当重要,对数据对象进行的操作都与它有关。当创建一个数据对象并插入 Managed Object Context 中,Managed Object Context 就开始跟踪这个数据对象的一切变动,并在合适的时候 供对 undo/redo 的支持,或 调用 Persistent Store Coordinato 将变化保存到数据文件中去。

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第4张图片

NSPersistentStoreCoordinator

使用 Core Data document 类型的应用程序,通常会从磁盘上的数据文中中读取或存储数据,这写底层的读写就由 Persistent Store Coordinator 来处理。一般我们无需与它直接打交道来读写文件,Managed Object Context 在背后已经为我们调用 Persistent Store Coordinator 做了这部分工作。

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第5张图片

NSFetchRequest

Fetch Requests 相当于一个查询语句,你必须指定要查询的 Entity。我们通过 Fetch Requests 向 Managed Object Context 查询符合条件的数据对象,以 NSArray 形式返回查询结果,如果我们没有设置任何查询条件,则返回该 Entity 的所有数据对 象。我们可以使用谓词来设置查询条件,通常会将常用的 Fetch Requests 保存到 dictionary 以重复利用。

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第6张图片
这里写图片描述

CoreDataManager

CoreDataManager.h

#import 
#import 

@interface CoreDataManager : NSObject
/**
 *  管理对象的上下文---管理协调器
 */
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

// 单例
+ (instancetype)sharedCoreDataManager;
@end

CoreDataManager.m

#import "CoreDataManager.h"

@implementation CoreDataManager

static CoreDataManager *manager;
#pragma mark - 创建coreDataManager单例
+ (instancetype)sharedCoreDataManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[self alloc] init];
    });
    return manager;
}

//// 沙盒路径
//- (NSURL *)applicationDocumentsDirectory {
//    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
//}

#pragma mark - 懒加载
- (NSManagedObjectContext *)managedObjectContext {
    if (_managedObjectContext == nil) {

        // 1.加载本地模型文件路径Person.xcdatamodeld
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"Person" withExtension:@"momd"];
        // 2.创建管理对象模型 -- 需要模型文件(.xcdatamodeld)的URL路径 -- 手动添加模型文件
        NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];

        // 3.数据库沙盒中的路径URL
        NSURL *storeURL = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"PersonCoreData.sqlite"];

        // 4.创建协调器 -- 协调模型文件和数据库
        NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
        // 5.协调器中添加数据库
        [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:nil];

        // 6.创建图形上下文----管理协调器
        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        // 7.添加协调器
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}
@end

Person.xcdatamodeld

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第7张图片

CoreData创建NSManageObject subclass

Xcode 8.1已经不能直接找到

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第8张图片

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第9张图片

默认生成.swift文件

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第10张图片

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第11张图片

Xcode 8.1 NSManagedObject subclass 编译报错 duplicate symbol OBJC_CLASS$_Person in:

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第12张图片

Xcode 8.1中,在使用Editor中的Create NSManagedObject Subclass 这个命令的时候,需要先把这个model的Codegen设置为Manual/None,否则会报错,在编译的时候。

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第13张图片

设置之后可能还会报错

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第14张图片
iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第15张图片

相互引用,删掉其中一个即可编译成功,这是Xcode的一个bug

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第16张图片

coredata读写数据

#import "ViewController.h"
#import "CoreDataManager.h"
#import "Person+CoreDataClass.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self updata];

    [self fetchRequestData];
}

#pragma mark - 写数据
- (void)updata {
    // 通过实体来向数据库插入数据
    // 通过Person.xcdatamodeld模型文件里添加的实体创建对象
    Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[CoreDataManager sharedCoreDataManager].managedObjectContext];

    // 赋值
    person.name = @"小明";
    person.age = 18;

    // 保存到数据库--上下文来保存
    [[CoreDataManager sharedCoreDataManager].managedObjectContext save:nil];
}

#pragma mark - 通过fetch request发送请求读数据
- (void)fetchRequestData {

    // 创建请求对象
    /**
     // 实体 - 从哪里的实体获取数据
     @property (nullable, nonatomic, strong) NSEntityDescription *entity;
     // 谓词 - 筛选条件 - 获取哪些数据
     @property (nullable, nonatomic, strong) NSPredicate *predicate;
     // 排序 升序还是降序
     @property (nullable, nonatomic, strong) NSArray *sortDescriptors;
     */
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    // 实体 - 从哪里的实体获取数据
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:[CoreDataManager sharedCoreDataManager].managedObjectContext];
    fetchRequest.entity = entity;

    // 谓词 - 筛选条件 - 获取哪些数据 (可选)
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",@"小明"];
    fetchRequest.predicate = predicate;

    // 排序 升序还是降序 - 数据库里可能有好几个叫小明的人 (可选)  ascending:YES 升序
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
    fetchRequest.sortDescriptors = @[sortDescriptor];

    // 执行请求,获取数据
    NSArray *PersonArr = [[CoreDataManager sharedCoreDataManager].managedObjectContext executeFetchRequest:fetchRequest error:nil];

    for (Person *person in PersonArr) {
        NSLog(@"%@----%lld",person.name,person.age);
    }

}
@end

效果

写入

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第17张图片

读出

iOS 开发 XMPP即时通讯项目开发(仿微信)-详解之Core data详解_第18张图片

参考:深入浅出Cocoa教程

你可能感兴趣的:(Core-Data,iOS开发)