开发者

Core data opening file dirty, inconsistently missing values, fetch returns empty array

开发者 https://www.devze.com 2023-01-30 15:36 出处:网络
I have a document based application running with core data. The object model has three entities with several properties. It seems to be working mostly alright—I can fill in some information and save

I have a document based application running with core data. The object model has three entities with several properties. It seems to be working mostly alright—I can fill in some information and save it, no problem. When I go to open the resulting file, however, it always opens "dirty," before I've even touched anything, and a few of the fields are sometimes blank.

What I mean is, sometimes you open the file and those fields show up empty and other times you open the file and they show up with the proper data. The properties that are blank are associated with only one of the entities and are displayed within the same NSTabView. They are some NSStrings displayed as both values in text fields and labels.

Update: Thanks to @ughoavgfhw's advice, I switched to an XML store and found two problems: that I was creating a new entity each time the document was开发者_如何学C opened in the [MyDocument init] instead of loading the saved one from the persistent store, but now I'm having problems fetching that one.

In the resulting XML file after a save, it does include this (the entity and properties that are giving me trouble):

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

and I attempt to fetch it with this:

- (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];
    }
}

After opening that persistent store, that request returns an empty array (and no error). Any tips on where to go from here?


Without code, all I can do is guess, but I would guess that you are doing some setup when you load the document. You do not disable undo registration, which is why you are having it marked as "dirty". There are a few reasons that data could not be loaded correctly. The two most likely situations are that: a) you override the data during your initialization, or b) the data is not being saved correctly, and therefore cannot be loaded correctly.

Here is how to disable undo registration:

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

Update for new information: Don't make any changes to core data in the init method. The windowControllerDidLoadNib: method is a better choice because everything has been loaded at that point. Here is an example that checks for an existing Story entity and creates a new one if needed:

- (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];
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号