How to switch from Core Data automatic lightweight migration to manual?

送分小仙女□ 提交于 2019-12-08 12:46:37

问题


My situation is similar to this question. I am using lightweight migration with the following code, fairly vanilla from Apple docs and other SO threads. It runs upon app startup when initializing the Core Data stack.

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
    nil];

NSError *error = nil;

NSString *storeType = nil;
if (USE_SQLITE) { // app configuration
    storeType = NSSQLiteStoreType;
} else {
    storeType = NSBinaryStoreType;
}

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

// the following line sometimes crashes on app startup
if (![persistentStoreCoordinator addPersistentStoreWithType:storeType configuration:nil URL:[self persistentStoreURL] options:options error:&error]) {
    // handle the error
}

For some users, especially with slower devices, I have crashes confirmed by logs at the indicated line.

I understand that a fix is to switch this to manual mapping and migration. What is the recipe to do that? The long way for me would be to go through all Apple docs, but I don't recall there being good examples and tutorials specifically for schema migration.


回答1:


There are good examples on how to do a manual migration but the basic steps are:

  • create a mapping model
  • include that mapping model with your project
  • turn off automigration

However, what is the crash? Are you being killed by the OS for taking too long? As a manual migration will not cure that.

What type of backing store are you using? If you are using binary it is possible to blow out memory because a migration will have two copies of the entire database in memory.

update from OP comment

I think I have seen this happen also with SQLite, so maybe there is something more than memory, although that is a valid point. Yes, it is killed by OS for taking too long, especially on 1G devices. I thought that manual migration was also a way to move from "migrate on app startup which has timeout constraints" to something which has no time constraints, and do it maybe on background thread or such. ?

There is no way to do the migration on a background thread because you are changing the source of the data. If your migration is taking too long on start up then the recommended solution is:

  • Let the -applicationDidFinishLaunching: cycle through the run loop complete without ever touching Core Data. This will stop that crash
  • Kick off the migration on the next iteration through the run loop (probably want to present some kind of progress indicator to the user) and complete the migration.

If you are using a binary store you are probably still going to have memory issues, but this will solve your crash on launch. The crash is the OS saying "I think you have locked up". By letting the -applicationDidFinishLaunching: complete you are telling the OS that you have not locked up.



来源:https://stackoverflow.com/questions/2654426/how-to-switch-from-core-data-automatic-lightweight-migration-to-manual

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