<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Migration on prometheus</title><link>https://new.halfrost.com/zh/categories/migration/</link><description>Recent content in Migration on prometheus</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><copyright>halfrost</copyright><lastBuildDate>Sun, 08 May 2016 08:06:00 +0000</lastBuildDate><atom:link href="https://new.halfrost.com/zh/categories/migration/index.xml" rel="self" type="application/rss+xml"/><item><title>iOS Core Data 数据迁移 指南</title><link>https://new.halfrost.com/zh/ios_coredata_migration/</link><pubDate>Sun, 08 May 2016 08:06:00 +0000</pubDate><guid>https://new.halfrost.com/zh/ios_coredata_migration/</guid><description>####前言 Core Data是iOS上一个效率比较高的数据库框架，(但是Core Data并不是一种数据库，它底层还是利用Sqlite3来存储数据的)，它可以把数据当成对象来操作，而且开发者并不需要在乎数据在磁盘上面的存储方式。它会把位于NSManagedObject Context里面的托管对象NSManagedObject类的实例或者某个NSManagedObject子类的实例，通过NSManagedObjectModel托管对象模型，把托管对象保存到持久化存储协调器NSPersistentStoreCoordinator持有的一个或者多个持久化存储区中NSPersistentStore中。使用Core Data进行查询的语句都是经过Apple特别优化过的，所以都是效率很高的查询。
当你进行简单的设定，比如说设定某个实体的默认值，设定级联删除的操作，设定数据的验证规则，使用数据的请求模板，这些修改Core Data都会自己完成，不用自己进行数据迁移。那那些操作需要我们进行数据迁移呢？凡是会引起NSManagedObjectModel托管对象模型变化的，都最好进行数据迁移，防止用户升级应用之后就闪退。会引起NSManagedObjectModel托管对象模型变化的有以下几个操作，新增了一张表，新增了一张表里面的一个实体，新增一个实体的一个属性，把一个实体的某个属性迁移到另外一个实体的某个属性里面…………大家应该现在都知道哪些操作需要进行数据迁移了吧。
####小技巧： 进入正题之前，我先说3个调试Core Data里面调试可能你会需要的操作。
1.一般打开app沙盒里面的会有三种类型的文件，sqlite，sqlite-shm,sqlite-wal,后面2者是iOS7之后系统会默认开启一个新的“数据库日志记录模式”(database journaling mode)生成的，sqlite-shm是共享内存(Shared Memory)文件，该文件里面会包含一份sqlite-wal文件的索引，系统会自动生成shm文件，所以删除它，下次运行还会生成。sqlite-wal是预写式日志(Write-Ahead Log)文件，这个文件里面会包含尚未提交的数据库事务，所以看见有这个文件了，就代表数据库里面还有还没有处理完的事务需要提交，所以说如果有sqlite-wal文件，再去打开sqlite文件，很可能最近一次数据库操作还没有执行。
所以在调试的时候，我们需要即时的观察数据库的变化，我们就可以先禁用这个日志记录模式，只需要在建立持久化存储区的时候存入一个参数即可。具体代码如下
NSDictionary *options = @{ NSSQLitePragmasOption: @{@&amp;#34;journal_mode&amp;#34;: @&amp;#34;DELETE&amp;#34;} }; NSError *error = nil; _store = [_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:options error:&amp;amp;error]; 2.Mac上打开数据库的方式很多，我推荐3个，一个是Firefox里面直接有sqlite的插件，免费的，可以直接安装，也很方便。当然也有不用Firefox的朋友，就像我是Chrome重度使用者，那就推荐2个免费的小的app，一个是sqlitebrowser，一个是sqlite manager，这2个都比较轻量级，都比较好用。
3.如果你想看看Core Data到底底层是如何优化你的查询语句的，这里有一个方法可以看到。
先点击Product -&amp;gt;Scheme -&amp;gt;Edit Scheme
然后再切换到Arguments分页中,在Arguments Passed On Launch里面加入 “- com.apple.CoreData.SQLDebug 3”,重新运行app，下面就会显示Core Data优化过的Sql语句了。
好了，调试信息应该都可以完美显示了，可以开始愉快的进入正文了！
####一.Core Data自带的轻量级的数据迁移 这种迁移可别小看它，在你新建一张表的时候还必须加上它才行，否则会出现如下的错误：
**Failed to add store. Error: Error Domain=NSCocoaErrorDomain Code=134100 &amp;#34;(null)&amp;#34; UserInfo={metadata={** ** NSPersistenceFrameworkVersion = 641;** ** NSStoreModelVersionHashes = {** ** Item = &amp;lt;64288772 72e62096 a8a4914f 83db23c9 13718f81 4417e297 293d0267 79b04acb&amp;gt;;** ** Measurement = &amp;lt;35717f0e 32cae0d4 57325758 58ed0d11 c16563f2 567dac35 de63d5d8 47849cf7&amp;gt;;** ** };** ** NSStoreModelVersionHashesVersion = 3;** ** NSStoreModelVersionIdentifiers = (** ** &amp;#34;&amp;#34;** ** );** ** NSStoreType = SQLite;** ** NSStoreUUID = &amp;#34;9A16746E-0C61-421B-B936-412F0C904FDF&amp;#34;;** ** &amp;#34;_NSAutoVacuumLevel&amp;#34; = 2;** **}, reason=The model used to open the store is incompatible with the one used to create the store}** 错误原因写的比较清楚了，reason=The model used to open the store is incompatible with the one used to create the store，这个是因为我新建了一张表，但是我没有打开轻量级的迁移Option。这里会有人会问了，我新建表从来没有出现这个错误啊？那是因为你们用的第三方框架就已经写好了改Option了。(场外人:这年头谁还自己从0开始写Core Data啊，肯定都用第三方框架啊)那这里我就当讲解原理了哈。如果是自己从0开始写的Core Data的话，这里是应该会报错了，解决办法当然是加上代码，利用Core Data的轻量级迁移，来防止这种找不到存储区的闪退问题</description></item></channel></rss>