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

时间:2010-12-16 00:52:41

标签: objective-c cocoa macos core-data

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

我的意思是,有时您打开文件并且这些字段显示为空,有时您打开文件并显示正确的数据。空白属性仅与其中一个实体相关联,并显示在同一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];
    }
}

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

1 个答案:

答案 0 :(得分:2)

没有代码,我所能做的只是猜测,但我猜你在加载文档时正在进行一些设置。您不会禁用撤消注册,这就是您将其标记为“脏”的原因。有几个原因无法正确加载数据。最可能的两种情况是: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];
}