我有一个使用Core Data进行存储的iPhone应用程序。我已经成功部署了它,现在我正在开发第二个版本。我遇到了数据模型的问题,在持久存储升级时需要一些非常简单的数据转换,所以我不能只使用默认的推断映射模型。
我的对象模型存储在.xcdatamodeld包中,版本1.0和1.1彼此相邻。版本1.1设置为活动版本。当我使用默认迁移行为并将NSInferMappingModelAutomaticallyOption设置为YES时,一切正常。我的sqlite存储从模型的1.0版本升级,一切都很好,当然,除了我需要完成的一些转换。
作为一个额外的实验步骤,我在核心数据模型包中添加了一个新的映射模型,并且没有对xcode生成的内容进行任何更改。当我运行我的应用程序(使用旧版本的数据存储)时,我得到以下
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'
我做错了什么?这是我获取托管对象模型和持久存储协调器的代码。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"gti_store.sqlite"]];
NSError *error;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:options
error:&error]) {
NSLog(@"Eror creating persistent store coodinator - %@", [error localizedDescription]);
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectModel *)managedObjectModel {
if(_managedObjectModel == nil) {
_managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
NSDictionary *entities = [_managedObjectModel entitiesByName];
//add a sort descriptor to the 'Foo' fetched property so that it can have an ordering - you can't add these from the graphical core data modeler
NSEntityDescription *entity = [entities objectForKey:@"Foo"];
NSFetchedPropertyDescription *fetchedProp = [[entity propertiesByName] objectForKey:@"orderedBar"];
NSSortDescriptor* sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"index" ascending:YES] autorelease];
NSArray* sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[[fetchedProp fetchRequest] setSortDescriptors:sortDescriptors];
}
return _managedObjectModel;
}
答案 0 :(得分:5)
我没有仔细考虑过这个问题,这只是一个观察,因为我遇到了同样的问题,而且我也发现很少有人在网上提到这个错误。
在我的情况下,问题是我已经设置了我的应用程序的一个对象来观察
NSManagedObjectContextObjectsDidChangeNotification如此
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(observeContextSave:)
name:NSManagedObjectContextDidSaveNotification
object:nil];
- (void) observeContextSave:(NSNotification*) notification {
[[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];}
我移动此代码以便在迁移后执行,错误就消失了。
反正。我确定你的情况不同。但是,考虑一下您对来自managedObjectContext的通知设置的观察结果可能会有所帮助。
更新:考虑到这一点后,我想这是因为在迁移期间创建了多个持久性存储,这意味着NSManagedObjectContextDidSaveNotification将从具有不同持久性存储的上下文发送到发送mergeChangesFromContextDidSaveNotification的上下文。
答案 1 :(得分:4)
首先,如果您有映射模型,请关闭自动迁移,它们碰撞的公平机会。完成后,确认错误已消失。
答案 2 :(得分:0)
从辅助线程执行持久存储初始化时,我遇到了类似的问题。在主线程中强制初始化后问题已经消失。怪异。
答案 3 :(得分:0)
似乎你已经修好了,但值得一提。我也有这个错误,原因是我有多个MOC被通知mergeChangesFromContextDidSaveNotification
,而他们有不同的持久存储(或不同的模式)。他们不知道如何处理不属于他们商店的变更。