为啥更改实体的属性时会删除我的 CoreData 信息?

Posted

技术标签:

【中文标题】为啥更改实体的属性时会删除我的 CoreData 信息?【英文标题】:Why is my CoreData info erased when changing the attributes of an entity?为什么更改实体的属性时会删除我的 CoreData 信息? 【发布时间】:2014-02-22 23:42:19 【问题描述】:

每次我向我的 CoreData 实体之一添加属性并运行应用程序时,都会出现异常,并且 CoreData 中的所有内容(我创建的所有对象)都会被删除。

在我的 AppDelegate 中:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator

    if (_persistentStoreCoordinator == nil) 
        NSURL *storeURL = [NSURL fileURLWithPath:[self dataStorePath]]
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
        NSError *error;

        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES error:&error])
        
            [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
            NSLog(@"Deleted old database %@, %@", error, [error userInfo]);
            [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@NSMigratePersistentStoresAutomaticallyOption:@YES error:&error];
            abort();
        
    
    return _persistentStoreCoordinator;


- (NSManagedObjectContext *)managedObjectContext

    if (_managedObjectContext == nil) 
        NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
        if (coordinator != nil) 
            _managedObjectContext = [[NSManagedObjectContext alloc] init];
            [_managedObjectContext setPersistentStoreCoordinator:coordinator];
        
    
    return _managedObjectContext;

我得到的错误:

2014-02-23 01:37:08.702 SoundQuiz[8063:70b] Deleted old database Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error 134130.)" UserInfo=0xc8796f0 URL=file:///Users/Eli/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/7041F45C-D3B2-4B9D-94A0-F5B68482D065/Documents/DataStore.sqlite, metadata=
    NSPersistenceFrameworkVersion = 479;
    NSStoreModelVersionHashes =     
        CategoryLevel = <f9824409 52866ec4 6a02251e d7b32d21 430cedd7 2b83ce04 1997e50c 2e0137d6>;
        GameCategory = <d65d9779 80986a4b da767cae b208d733 7944cebf c146e242 e7c9f0ff fc06eb31>;
        LevelSound = <2b23da4d ef82c20d 68a5de45 efb7b2f0 26621867 68904b04 04144acb 44fd43fd>;
    ;
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
        ""
    );
    NSStoreType = SQLite;
    NSStoreUUID = "A28E8265-2D65-439E-9634-55482C4ED9F0";
    "_NSAutoVacuumLevel" = 2;
, reason=Can't find model for source store, 
    URL = "file:///Users/Eli/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/7041F45C-D3B2-4B9D-94A0-F5B68482D065/Documents/DataStore.sqlite";
    metadata =     
        NSPersistenceFrameworkVersion = 479;
        NSStoreModelVersionHashes =         
            CategoryLevel = <f9824409 52866ec4 6a02251e d7b32d21 430cedd7 2b83ce04 1997e50c 2e0137d6>;
            GameCategory = <d65d9779 80986a4b da767cae b208d733 7944cebf c146e242 e7c9f0ff fc06eb31>;
            LevelSound = <2b23da4d ef82c20d 68a5de45 efb7b2f0 26621867 68904b04 04144acb 44fd43fd>;
        ;
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
            ""
        );
        NSStoreType = SQLite;
        NSStoreUUID = "A28E8265-2D65-439E-9634-55482C4ED9F0";
        "_NSAutoVacuumLevel" = 2;
    ;
    reason = "Can't find model for source store";

我似乎找不到我的问题。修改实体时是否总是需要创建新的模型版本?我以为它会自动迁移?

【问题讨论】:

【参考方案1】:

如果您创建 Core Data 存储,然后在没有先创建新模型版本且未启用自动迁移(模型升级)的情况下编辑 Core Data 模型并再次运行应用程序,您将收到上述错误和现有存储不会打开。

所以首先你需要设置下面的 persistentStoreCoordinator 选项

@NSMigratePersistentStoresAutomaticallyOption:@YES,
             NSInferMappingModelAutomaticallyOption:@YES

然后您需要通过在 Xcode 中选择现有模型,然后从 Xcode 的 Editor 菜单中选择 Add Model Version 来创建新的模型版本。现在确保您选择了新的模型版本,并在 Xcode 右侧的详细信息面板中将其设置为当前模型(应该有一个绿色的勾号)。

现在您对新模型进行了更改,当您运行应用程序时,它应该升级现有模型。

或者,如果您仍处于开发初期并且不关心现有 Core Data 存储中的内容,只需在再次运行应用程序之前将其删除即可。

【讨论】:

以上是关于为啥更改实体的属性时会删除我的 CoreData 信息?的主要内容,如果未能解决你的问题,请参考以下文章

Core Data + iCloud,更改通知插入和删除关系中的对象但不更新关系中现有实体的属性

ios coredata 会在新版本中更改实体属性导致崩溃

从实体中删除属性后迁移 CoreData 时出错

删除 CoreData 实体中的所有记录

Coredata 手动迁移

为啥 EF 在分离时会删除子实体?