Iphone 具有多个通道的标准核心数据迁移不起作用
我在这里学习了有关核心数据标准迁移的教程: 然后是一个关于多次传球的例子: 这给了我这里的结果代码:Iphone 具有多个通道的标准核心数据迁移不起作用,iphone,objective-c,ios,core-data,core-data-migration,Iphone,Objective C,Ios,Core Data,Core Data Migration,我在这里学习了有关核心数据标准迁移的教程: 然后是一个关于多次传球的例子: 这给了我这里的结果代码: - (NSManagedObjectContext *)managedObjectContext { if (managedObjectContext != nil) { return managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persiste
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [TICDSSynchronizedManagedObjectContext new];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
// managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"EntryDatabase" ofType:@"momd"];
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSString *storePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"CoreDataStore.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
NSLog(@"file exists at path: %@, %i", storePath, [fileManager fileExistsAtPath:storePath]);
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"CoreDataStore" ofType:@"sqlite"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSError *error;
NSDictionary *pscOptions = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:NO], NSInferMappingModelAutomaticallyOption,
nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:pscOptions
error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
return persistentStoreCoordinator;
}
- (BOOL)checkForMigration
{
BOOL migrationSuccess = NO;
NSString *storeSourcePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"CoreDataStoreNew.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storeSourcePath]) {
//Version 2 SQL has not been created yet, so the source is still version 1...
storeSourcePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"CoreDataStore.sqlite"];
}
NSURL *storeSourceUrl = [NSURL fileURLWithPath: storeSourcePath];
NSError *error = nil;
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator
metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeSourceUrl
error:&error];
if (sourceMetadata) {
NSString *configuration = nil;
NSManagedObjectModel *destinationModel = [self.persistentStoreCoordinator managedObjectModel];
//Our Source 1 is going to be incompatible with the Version 2 Model, our Source 2 won't be...
BOOL pscCompatible = [destinationModel isConfiguration:configuration compatibleWithStoreMetadata:sourceMetadata];
NSLog(@"Is the STORE data COMPATIBLE? %@", (pscCompatible==YES) ?@"YES" :@"NO");
if (pscCompatible == NO) {
migrationSuccess = [self performMigrationWithSourceMetadata:sourceMetadata toDestinationModel:destinationModel];
}
}
else {
NSLog(@"checkForMigration FAIL - No Source Metadata! \nERROR: %@", [error localizedDescription]);
}
return migrationSuccess;
}
- (BOOL)performMigrationWithSourceMetadata :(NSDictionary *)sourceMetadata
toDestinationModel:(NSManagedObjectModel *)destinationModel
{
BOOL migrationSuccess = NO;
//Initialise a Migration Manager...
NSManagedObjectModel *sourceModel = [NSManagedObjectModel mergedModelFromBundles:nil
forStoreMetadata:sourceMetadata];
//Perform the migration...
if (sourceModel) {
NSMigrationManager *standardMigrationManager = [[NSMigrationManager alloc]
initWithSourceModel:sourceModel
destinationModel:destinationModel];
NSArray *mappingModelNames = [NSArray arrayWithObjects:@"StepOne", @"StepTwo", nil];
NSDictionary *sourceStoreOptions = nil;
NSString *destinationStorePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"CoreDataStoreNew.sqlite"];
NSURL *destinationStoreURL = [NSURL fileURLWithPath: destinationStorePath];
NSString *destinationStoreType = NSSQLiteStoreType;
NSDictionary *destinationStoreOptions = nil;
for (NSString *mappingModelName in mappingModelNames) {
NSError *error;
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:mappingModelName withExtension:@"cdm"];
NSMappingModel *mappingModel = [[NSMappingModel alloc] initWithContentsOfURL:fileURL];
migrationSuccess = [standardMigrationManager migrateStoreFromURL:destinationStoreURL
type:NSSQLiteStoreType
options:sourceStoreOptions
withMappingModel:mappingModel
toDestinationURL:destinationStoreURL
destinationType:destinationStoreType
destinationOptions:destinationStoreOptions
error:&error];
NSLog(@"Error: %@", error);
}
}
return migrationSuccess;
}
但是,应用程序内存不足,并在persistentStoreCoordinator
中的一行崩溃:
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:pscOptions
error:&error]) {
我记得我也遵循了这个教程 事实上,我发现这样做是不对的。顺便问一下,您是否阅读了关于该教程的最后一条评论,并尝试删除提到的行?也许这能解决你的问题 无论如何,在我的例子中,我意识到(在遵循本教程之后,修改没有帮助)有一种更简单的方法
在你的情况下,我不知道,但是,如果这个小修改不能解决它,我真的会寻找另一个参考-因为这真的不是正确的方法,并导致你在错误的方向上,因为它试图自己做所有事情,而不是像我发现的那样使用苹果核心数据迁移过程背后的逻辑。几年前我解决的问题是从一个存储库中取出一个子树,然后复制到另一个存储库中,我所做的应该对你有用。我是在Mac上这样做的,所以内存不是问题,但是根据核心数据编程指南“减少内存开销”,通过适当的故障处理和减少内存,您应该能够让它正常工作 下面的解决方案基于这样一个假设,即MOM没有那么大的不同。让我介绍“A”一词用于现有上下文,而“B”一词用于新上下文 1) 第一步是在B中复制A中的每个对象。如果类保持不变,则可以。这意味着对于每个对象,都需要一个包含实体中所有值的列表。我建议使用键——每个实体类型的属性键数组,这将使编码更容易(如果可以的话)。否则,你实际上可以从妈妈那里得到钥匙——这就是我在旧代码中所做的 现在关键的一步是——你必须创建一个翻译词典(也许你需要两个——我已经创建了),对于a中的每个实体,你都知道“B”中对应的那个。您可以使用'objectID'属性(但对于B,在保存此值更改后,在完成之前不要进行保存) 2) 现在您已经完全重新创建了所有实体,您需要将它们“连接”起来,以便正确设置所有关系。同样,为每个实体类型创建一些键数组,然后在循环中查看“a”中的每个关系,获取它指向的实体,使用转换表在“B”中找到相应的一个,并在“B”中设置值 瞧!完成了。很明显,你做的是添加还是删除?你做上述操作是为了反映A-B中的更改
同样,我也不需要太担心Mac上的内存,所以也不需要技巧来降低内存。我相信使用faulting('refreshObject:mergeChanges:')会对您有所帮助,但您也不必这样做(即便如此,可能只是对象太大了)。您刚才不是也发过同样的问题吗?如果不是的话,其他一些人发布了几乎完全相同的东西。我现在确实有了一个想法,因为我没有earler,因为我使用了一种在这里也应该有效的技术(但它不是微不足道的),将在文本编辑器中编写,然后稍后添加。@DavidH我已经就同一代码问了其他问题。期待看到你的替代品。你删除了那些线路了吗。你发现了哪种替代方案?事实证明,我的案例非常简单-因此我所要做的就是使用添加了所有新属性和关系的正常迁移-我不确定它是否适用于你。抱歉,但我能给出的唯一建议是重新检查您的新数据模型,看看您是否真的需要更复杂的转换…-在我的情况下(在我了解了leightweight可以做什么之后),这就是我所需要的