如何正确更新 Xcode4 中的模型而不损坏它?
我在使用 Xcode3 时从未遇到过任何问题,但在使用 Xcode4 时,当我更新核心数据模型时,苹果代码大约 3 次失败,出现可怕的“持久存储迁移失败,缺少源托管对象模型”。错误。
这是我的设置(我如何将项目配置为自动迁移):
- NSPersistentDocument,来自 Apple 的模板
- 覆盖 Apple 的模型加载方法,我唯一要做的就是在 storeOptions Dictionary 中提供两个标志,这两个标志打开自动迁移
-(BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error
{
NSMutableDictionary *newOptions = nil;
if( storeOptions != nil )
newOptions = [NSMutableDictionary dictionaryWithDictionary:storeOptions];
else
newOptions = [NSMutableDictionary dictionary];
[newOptions setValue:@"YES" forKey:NSMigratePersistentStoresAutomaticallyOption];
[newOptions setValue:@"TRUE" forKey:NSInferMappingModelAutomaticallyOption];
BOOL success = FALSE;
success = [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newOptions error:error];
return success;
}
这是我一直在使用的过程(它已经解决了 Xcode4 中的 1 个错误!)
- 选择模型(在 Xcode4 中名为“something.xcdatamodel”,其中左侧的曲折)
- 转到编辑器菜单,选择“添加新模型版本...”
- 将新版本命名为比上一个大的 1 整数 - 例如,如果前一个版本为“4”,则将新版本命名为“5”
- 。窗格中,将当前模型版本更改为新创建的
- XCode4 bug 解决方法:选择任意文件,然后选择新创建的模型。如果不这样做,Xcode 会显示新创建的模型上的选择,但会编辑以前的模型,这肯定会破坏 CoreData 中的所有内容
- 。在本例中,我将向现有实体“保存”添加新属性
- 。建造。跑步。 ... 碰撞。
不过,正如我所说,大约 3 次中有 2 次这是正确的。一旦它工作一次,它(显然)就很好 - 轻量级迁移完成,下一次保存将保存在新的模型版本中。
所以我猜我在上述步骤中做错了什么,但我已经浏览了文档 5 或 6 次,看不到任何明显的东西。 NSPersistentDocument 文档都已经过时了,这并没有什么帮助——但我也多次在 iPhone 上进行了轻量级迁移,所以我对这样做很有信心,而且这对我来说似乎是正确的。
我尝试过/检查过的其他事情: - iPhone核心数据轻量级迁移 Cocoa 错误 134130:找不到源存储的模型(不;只有根xcdatamodel 被包括在内)
I never had any problems with Xcode3, but with Xcode4 I'm getting Apple's code failing approx 1 time in 3 when I update a core data model, with the dreaded "Persistent store migration failed, missing source managed object model." error.
Here's my setup (how I configured the project to auto-migrate):
- NSPersistentDocument, from Apple's template
- Override Apple's model-loading method, and the ONLY thing I do is to provide the two flags in the storeOptions Dictionary, which turn on auto-migration
-(BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error
{
NSMutableDictionary *newOptions = nil;
if( storeOptions != nil )
newOptions = [NSMutableDictionary dictionaryWithDictionary:storeOptions];
else
newOptions = [NSMutableDictionary dictionary];
[newOptions setValue:@"YES" forKey:NSMigratePersistentStoresAutomaticallyOption];
[newOptions setValue:@"TRUE" forKey:NSInferMappingModelAutomaticallyOption];
BOOL success = FALSE;
success = [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newOptions error:error];
return success;
}
Here's the process I've been using (which is already working around 1 bug in Xcode4!)
- Select the model (named "something.xcdatamodel" in Xcode4, with a twisty on the left)
- Go to Editor menu, select "Add new model version..."
- Name the new version 1 integer higher than last - e.g. if previous was "4" name the new one "5"
- In the right-hand pane, change the current model version to the newly-created one
- workaround for XCode4 bug: select any file, then select the newly-created model. If you do not, Xcode shows the selection on the newly-created model, but will edit the previous model instead, which definitely corrupts everything in CoreData
- Edit your model; in this case, I'm adding a new attribute to an existing entity
- Save. Build. Run. ... CRASH.
Except, as I said, approx 2 times in 3 this works correctly. Once it works once, it's (obviously) fine - the lightweight migration is complete, the next save saves in the new model version.
So I'm guessing there's something I'm doing wrong in the above steps, but I've been through the docs 5 or 6 times and can't see anything obvious. Doesn't help that NSPersistentDocument docs are all out of date - but I've done lightweight migration on iPhone lots of times too, so I'm reasonably confident with doing this, and it seems right to me.
Other things I've tried/checked:
- iPhone Core Data Lightweight Migration Cocoa error 134130: Can't find model for source store (nope; only the root xcdatamodel was being included)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用
[NSNumber numberWithBool:YES]
而不是@"YES"
或@"TRUE"
。Use
[NSNumber numberWithBool:YES]
not@"YES"
or@"TRUE"
.由于您已经消除了作为问题根源的损坏的开发存储,因此我怀疑问题出在 Xcode 4.x 中,至少可以说这是有问题的。很多人都报告了类似的问题,但没有两个问题看起来完全相同。这可能是一个仅在特定数据模型设置中出现的错误,因此问题将很难追踪。
您可能只需放弃自动迁移并创建显式迁移映射。它需要更长的时间并给您的代码带来复杂性,但它总是有效的。
如果您有一个运输应用程序并且将在野外处理最终用户数据,那么您确实有道德和商业义务采取额外的步骤来保护最终用户数据。
Since you have eliminated a corrupt development store as a source of the problem, I suspect the problem lays in Xcode 4.x which is buggy to say the least. A lot of people are reporting similar issues but no two problems seem exactly the same. It is probably a bug/s that only occur with specific data model setups so the problem will be very hard to track down.
You may simply have to abandon automatic migration and create an explicit migration map. It takes longer and introduces complexity into your code but it will always work.
If you have a shipping app and will be dealing with end user data in the wild, you do have a moral and business obligation to take the extra step to protect end user data.
我非常困惑,但是这个,它不起作用......因为我假设该方法已经有一个“存储选项”字典......我只需要在设置上述选项之前检查它是否存在......
I was getting super-confused but this, and it WASN'T working.. because I was assuming that the method would already HAVE a "store options" dictionary.. I just needed to check for it's existence before i set the aforementioned options…