iOS8.1 Core-Data Lightweight + Heavyweight Migration

a 夏天 提交于 2021-02-10 09:41:39

问题


I have Version 1 of my core-data database. (Reduced example)

enter image description here

I make some changes to the model, making V2. This involves creating a new entity with type attribute plus a few others. The type attribute is the link to the plate entity. enter image description here

The new version of my app is released and the data migrates ok as this is lightweight. For my own reasons at the time, I did not create a relationship at this time.

Sometime later I decide to do some bigger changes to the structure, creating new entities FixtureType and PlateTypeImage. I then create some relationships. This gives me V3 of my model.

enter image description here

Because of the nature of this modification I need to do heavyweight migration from V2 to V3 which involves copying attribute data, populating new attributes and setting the relationships as I go. So, I set up a mapping model, create my necessary migration policies and hit the go button.

This works for V2 to V3 but when testing a migration from V1 to V3, I get a series of errors..., such as

reason=Cannot migrate store in-place: Validation error missing attribute values on mandatory destination relationship

I'm using the following PSC options:

NSDictionary *options = @{
                          NSMigratePersistentStoresAutomaticallyOption : @YES,
                          NSInferMappingModelAutomaticallyOption : @YES
                          };


if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

So, my query is how does core-data migrate the data? Is it sequentially, so I get a lightweight migration from V1 to V2, then heavyweight V2 to V3, or does it do a migration from V1 to V3? If so, do I need to create a migration policy for V1 to V3 (making things unwieldy very quickly to cover every combination)?

Also, have I now lost the lightweight migration facility, once I start using heavyweight?

Advice and comments appreciated.


回答1:


Core Data versioning is not temporal. It only knows source and destination. Therefore, as soon as you introduce a new model you need to test from all previous models to the current model.

If you add V4, then you need to test for:

V1->V4
V2->V4
V3->V4

So if your V4 requires a heavy migration then you need to do a map for each possible migration.

My general recommendation is to avoid heavy migrations at all costs. They are not designed to work on iOS and frequently cause issues. There are alternatives that will perform better.

Better Approaches

Two most common approaches I use instead of heavy migration is

  1. Export/Import. I use JSON for this. It is easier on memory and therefore can avoid crashes due to memory constraints.

  2. Clever pre and post migration code. For example, if you are splitting data out to a new object, something that requires a heavy migration, you could create the new object and leave the data in the old object. This would turn it into a lightweight migration. From there you could watch for the migration and then move the data manually after the migration is complete. You could even then do another lightweight migration to a final model that doesn't include the soon to be removed attributes.

Keep in mind that iCloud doesn't allow heavy migration so if you are ever going to consider using iCloud then you must skip heavy migration. This is also a very strong indicator that Apple is slowing deprecating heavy migration and leaving it in place as a "last resort" maneuver.



来源:https://stackoverflow.com/questions/27023121/ios8-1-core-data-lightweight-heavyweight-migration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!