coreData -最新版

CoreData概念

coredata是对sqlite的封装,提供ORM机制,可以直接把oc对象保存到数据库,简单,高效,适合操作大批量数据的存储和查询,是最合适的数据管理方式

ORM:就是coreData提供的oc对象和数据的映射关系的功能。 可以把oc对象转化数据保存sqlite数据库中,也可以把从sqlite获取的数据转化为oc对象。

coredata核心结构图

image

PersistentObjectStore:PS,存储持久对象的数据库(例如SQLite,注意CoreData也支持其他 类型的数据存储,例如xml、二进制数据等)。

PersistentStoreCoordinator 持久化存储助理,对象模型和实体类之间的转化协调器,用于管理不同存储对象的上下文

ManagedObjectContext:对象管理上下文,负责实体对象和数据库之间的交互。比如插入,删除,查询,

ManagedObjectModel:被管理的数据对象模型,对应Xcode中创建的模型文件,用来读取app中的所有数据实体

NSEntityDescription:数据实体的描述,相当于数据库的一个表,描述实体间的关系

最底层是PersistentObjectStore, ManagedObjectModel: 就是数据转为成对象的模板

为什么说Coredata的多线程是不安全的

在使用coredata 保存数据的过程中,我们使用NSManagetObjectContext 来对数据进行读写操作,为了提供效率,一般会使用两个context,一个context在主线程负责与UI的交互,一个context在子线程负责数据的读写,这样就很有可能造成数据的不同步。所以说coredata是多线程是不安全的

coredata多线程数据安全的解决办法(也就是coredata的多线程正确实现方式有哪些)(多个context自动同步数据的方式有哪些?)

方式1 两个context 使用同一个持久化存储助理psc 。一个context处理完数据后通过通知的方式通知 另一个context 调用mergeChangeFromContextDidSavaNotification来自动同步数据 (需实践)

方式2: 给context 设置parentContext 一个parentContext 可以有多个childContext。而childContext的没有实际的psc指针 ,所以childcontext的save操作实际上只是同操作push给parentContext来完成真正的save操作,这样就实现了数据同步,这也是coredata 两层,三层结构的原理

什么是数据冲突? 数据冲突产生的原因是什么? 如何解决数据冲突?

数据冲突,只多个context的方法,不同的context的fetch操作(主要指修改和删除)对同一个managerobject进行了不同的修改,从而导致的数据数据冲突,会让两个context都保存失败。

数据冲突产生的原因: context的fetch会对会对持久化操作处理ps里的状态进行快照,保存时会让快照和ps当前的状态就行对比,如果不一致,说明用户进行了修改,但如果这个修改不是当前context的操作,会导致context的状态不连续,从而无法保存

数据冲突使用合并策略解决 1.NSErrorMergePolicy 什么也不做,但会返回错误信息 2。NSMergeByPropertyStoreTrumpMergePolicy优先使用ps的快照(即使用本地数据库) 3。NSMergeByPropertyObjectTrumpMergePolicy 使用准备保存的context的内容 4.NSOverWriteMergePolicy:准备保存的context覆盖ps快照(本地数据库部分) 5.NSRollBackMergePolicy 回滚,放弃修改,直接使用本地数据库进行版本替换

如何创建2个context

1 主线程context的类型采用NSMainQueueConcurrentcyType 2,子线程context的类型采用NSPrivateQueueConCurrentcyType。这样context会自动放入子线程中

其他coredata小知识

1.context的performBlock是自动异步操作

2.context的performBlockAndWait是同步执行

3.ios10中的NSManagerObjectContext(管理上下问)从NSPersistentCotainer的viewContext获取,无需手动创建 4.ios8之后NSManageObject subclass实体类的创建时需要在右侧将实体的Codegen改为Manage/None

当sqlite的读写是分线程的,遇到过死锁没?咋解决的

使用Sqlite的时候遇到过思索,当时项目没有使用FMDB,是自己直接使用sql语句实现数学库的增删改查,而且当前的情况是开发环境正常,发布的包才会出问题,最后通过debug 打印日志知道是“数据库文件被锁,无法访问”的错误,通过使用FMDB来操作数据库解决了问题,

后期通过学习FMDB指导,解决问题的根本原因是FMDB全局使用唯一FMDataBaseQueue,内部维护一个串行队列来控制app对数据库的访问,也就是说app只有dbqueue对象来操作数据库,所有的操作到都是在子线程中串行执行,自然不会死锁

在使用SQLite过程中,如果多条线程同时操作同一数据库会造成什么问题,怎么解决?

多条线程同时操作同一数据库,容易造成死锁。系统崩溃 解决方案:使用串行模式操作数据库,即使用单利的方式操作数据库,比如FMDB就是这种原理

JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里属于IT工程师。