核心数据打开文件脏,缺失值不一致,fetch返回空数组

Posted

技术标签:

【中文标题】核心数据打开文件脏,缺失值不一致,fetch返回空数组【英文标题】:Core data opening file dirty, inconsistently missing values, fetch returns empty array 【发布时间】:2010-12-16 00:52:40 【问题描述】:

我有一个使用核心数据运行的基于文档的应用程序。对象模型具有三个具有多个属性的实体。它似乎工作得很好——我可以填写一些信息并保存它,没问题。然而,当我打开生成的文件时,它总是在我还没有触及任何东西之前打开“脏”,并且一些字段有时是空白的。

我的意思是,有时您打开文件,这些字段显示为空,有时您打开文件,它们显示正确的数据。空白的属性仅与其中一个实体相关联,并显示在同一个NSTabView 中。它们是一些 NSStrings 在文本字段和标签中显示为值。

更新: 感谢@ughoavgfhw 的建议,我切换到XML 存储并发现两个问题:每次在[MyDocument init] 中打开文档时我都在创建一个新实体,而不是从持久存储中加载保存的实体,但现在我'我在获取那个时遇到了问题。

在保存后生成的 XML 文件中,它确实包含以下内容(给我带来麻烦的实体和属性):

<object type="STORY" id="z102">
    <attribute name="title" type="string">test 6</attribute>
    <attribute name="descript" type="string">this is a test</attribute>
</object>

我尝试用这个来获取它:

- (Story *)getSavedStory 
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Story" inManagedObjectContext:[self managedObjectContext]];
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:entityDescription];
    NSError *error = nil;
    NSArray *array = [[self managedObjectContext] executeFetchRequest:request error:&error];
    if (array == nil) 
        NSLog(@"%@",error);
        return nil;
     else 
        return [array lastObject];
    

打开该持久存储后,该请求返回一个空数组(并且没有错误)。关于从这里去哪里的任何提示?

【问题讨论】:

你能贴出你打开文件的代码吗? 我还没有写任何具体的东西来处理这个问题,所以我很确定它继承了 NSPersistentDocument 的功能。 【参考方案1】:

没有代码,我所能做的就是猜测,但我猜你在加载文档时正在做一些设置。您没有禁用撤消注册,这就是您将其标记为“脏”的原因。无法正确加载数据有几个原因。最可能的两种情况是:a) 您在初始化期间覆盖了数据,或者 b) 数据未正确保存,因此无法正确加载。

以下是如何禁用撤消注册:

NSManagedObjectContext *moc; //In your document subclass, get this with [self managedObjectContext];
[moc processPendingChanges];
[[moc undoManager] disableUndoRegistration];
//Make changes here
[moc processPendingChanges];
[[moc undoManager] enableUndoRegistration];

更新新信息: 不要对 init 方法中的核心数据进行任何更改。 windowControllerDidLoadNib: 方法是更好的选择,因为此时所有内容都已加载。这是一个检查现有 Story 实体并在需要时创建新实体的示例:

- (void)windowControllerDidLoadNib:(NSWindowController *)windowController 
    [super windowControllerDidLoadNib:windowController];
    NSFetchRequest *req = [[NSFetchRequest alloc] init];
    [req setEntity:[NSEntityDescription entityForName:@"Story" inManagedObjectContext:[self managedObjectContext]]];
    NSError *err = nil;
    NSArray *objs = [[self managedObjectContext] executeFetchRequest:req error:&err];
    [req release];
    if(!objs) 
        [[NSAlert alertWithError:err] runModal];
        return;
    
    NSManagedObject *story = nil;
    if([objs count] == 0) 
        [[self managedObjectContext] processPendingChanges];
        [[self undoManager] disableUndoRegistration];
        story = [NSEntityDescription insertNewObjectForEntityForName:@"Story" inManagedObjectContext:[self managedObjectContext]];
        //Additional setup
        [[self managedObjectContext] processPendingChanges];
        [[self undoManager] disableUndoRegistration];
     else story = [objs lastObject];

【讨论】:

您有关于检查如何保存的提示吗?这几乎只是商店、文档子类和 nib 绑定​​之间的直接连接,因此我倾向于将其作为可能的解决方案。同样,我正在使用内置的保存功能。 使用 XML 存储格式(我在使用 CoreData 时总是有一个用于测试的格式)并在文本编辑器中打开它以确保一切都在那里。如果出现问题,则需要检查所有连接并确保自定义类在更改时发送 KVC 通知。 好的,谢谢,我会试试的。一个问题。我最终需要将它移回 SQLite,所以在我投入太多时间之前,您是否预见到我应该注意的任何问题? 存储类型之间的唯一区别是它在磁盘上的表示方式。只需使用 XML,您就可以轻松读取正在存储的内容。如果它适用,它也适用于二进制或 SQLite。 我尝试了你所说的并取得了一些进展。我想我正在接近一个完整的解决方案。我用新信息更新了问题。

以上是关于核心数据打开文件脏,缺失值不一致,fetch返回空数组的主要内容,如果未能解决你的问题,请参考以下文章

数据清洗

罕见病数据库构建与应用专栏|不同类型“脏数据”的清洗方式

数据预处理

R语言︱异常值检验离群点分析异常值处理

如何使用R语言解决可恶的脏数据

数据质量及数据清洗方法