核心数据实体关系在启动之间不保存 [英] Core Data Entity Relationship Does Not Save Between Launches

查看:176
本文介绍了核心数据实体关系在启动之间不保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,它有四个主要实体,它们都通过关系链接。一些是一对一,一些是一对多。在初始加载时,三个实体将其数据从本地存储的XML文件加载到应用程序,并且其中一个实体从Web下载XML并从其加载其数据。当应用程序加载它执行检查,以查看每个这些文件的数据是否比当前有更新的,如果是,它将替换该实体中的所有当前数据与来自相应文件的数据。

I am writing an application that has four main entities that are all linked via relationships. Some are one to one, some are one to many. Upon initial load, three of the entities load their data from XML files stored locally to the application and one of the entities downloads an XML from the web and loads its data from it. When the app loads it performs a check to see if the data from each of these files is more recent than what it currently has and, if so, it will replace all current data in that entity with data from the appropriate file.

作为我在编写期间的调试过程的一部分,我一直强制删除所有数据。当调用删除函数并在应用程序启动时加载所有数据时,应用程序运行良好,所有实体和关系的行为都与它们应该一样。但是,当我删除对delete函数的调用,并执行检查并尝试从其存储的数据运行,所有的关系似乎都消失了。在调试这个,我发现所有的实体确实包含他们应该的所有常规数据,他们只是没有关系了。我不知道为什么在世界上的关系是保存在第一次加载,但不保留,当所有的数据没有重新导入。

As part of my debug process during writing I have been forcing a delete of all data. When the delete function is called and all data is loaded at app launch the application runs beautifully and all entities and relationships behave exactly as they should. However, when I remove the call to the delete function and it performs the checks and tries to run from data it has stored, all of the relationships seem to disappear. In debugging this, I have found that all of the entities do contain all of the regular data that they are supposed to, they just don't have the relationships anymore. I can't figure out why in the world the relationships are saved on first load but don't retain when all data is not re-imported.

我想象一些代码将有助于任何调试,但是,我不知道我应该包括多少。所以,我将开始只包括在数据加载类中调用的一个方法。如果有什么事情有帮助,请让我知道。非常感谢任何帮助。

I would imagine some code would be helpful to anyone debugging, however, I'm not sure how much I should include. So, I will start by including just one of the methods called in the data loading class. If anything else would help, please let me know. Any help is very much appreciated.

更新代码:2/25/11(根据建议 - 问题仍然存在)
更新代码:2/25 / 11 - 问题解决

UPDATED CODE: 2/25/11 (Based on Suggestions - Problem still exists) UPDATED CODE: 2/25/11 - Problem Solved

- (NSArray *) loadFeatures {

    if ([self checkForUpdate:@"Features"]) {

        [self deleteAllObjects:@"Features"];

        NSString *filePath = [self dataFilePath:FALSE withResourceName:@"Features"];
        NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
        NSError *error;
        GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];

        NSArray *featureElements = [doc.rootElement elementsForName:@"FEATURE"];
        NSMutableSet *featureSections = [[NSMutableSet alloc] init];

        for (GDataXMLElement *featureElement in featureElements) {

            NSString *featureName = nil;
            NSNumber *featureSecure = nil;
            NSNumber *featureID = nil;
            NSNumber *featureSortKey = nil;
            DisplayTypes *featureDisplayType = nil;

            NSArray *names = [featureElement elementsForName:@"NAME"];
            if (names.count > 0) {
                GDataXMLElement *firstName = (GDataXMLElement *) [names objectAtIndex:0];
                featureName = firstName.stringValue;
            } else continue;

            NSArray *secures = [featureElement elementsForName:@"SECURE"];
            if (secures.count > 0) {
                GDataXMLElement *firstSecure = (GDataXMLElement *) [secures objectAtIndex:0];
                featureSecure = [NSNumber numberWithInt:firstSecure.stringValue.intValue];
            } else continue;

            NSArray *featureIDs = [featureElement elementsForName:@"FEATUREID"];
            if (featureIDs.count > 0) {
                GDataXMLElement *firstFeatureID = (GDataXMLElement *) [featureIDs objectAtIndex:0];
                featureID = [NSNumber numberWithInt:firstFeatureID.stringValue.intValue];
            }

            NSArray *featureSortKeys = [featureElement elementsForName:@"SORTKEY"];
            if (featureSortKeys.count > 0) {
                GDataXMLElement *firstSortKey = (GDataXMLElement *) [featureSortKeys objectAtIndex:0];
                featureSortKey = [NSNumber numberWithInt:firstSortKey.stringValue.intValue];
            }

            NSArray *featureDisplays = [featureElement elementsForName:@"DISPLAYTYPEID"];
            if (featureDisplays.count > 0) {
                GDataXMLElement *firstFeatureDisplay = (GDataXMLElement *) [featureDisplays objectAtIndex:0];

                for (DisplayTypes *thisDisplayType in self.displayTypes) {
                    if (thisDisplayType.displayTypeID == [NSNumber numberWithInt:firstFeatureDisplay.stringValue.intValue]) {
                        featureDisplayType = thisDisplayType;
                    }
                }
            }

            NSArray *sectionElements = [featureElement elementsForName:@"SECTIONS"];


            for (GDataXMLElement *sectionElement in sectionElements) {

                NSArray *sectionIDs = [sectionElement elementsForName:@"SECTION"];

                for (GDataXMLElement *sectionID in sectionIDs) {
                    NSArray *thisSectionIDs = [sectionID elementsForName:@"SECTIONID"];
                    if ([thisSectionIDs count]) {
                        GDataXMLElement *thisSectionID = (GDataXMLElement *) [thisSectionIDs objectAtIndex:0];

                        for (Sections *thisSection in self.sections) {

                            if ([thisSection.sectionID isEqualToNumber:[NSNumber numberWithInt:thisSectionID.stringValue.intValue]]) {
                                [featureSections addObject:thisSection];
                            }

                        }
                    }
                }
            }


            NSManagedObjectContext *context = [self managedObjectContext];
            NSManagedObject *featureInfo = [NSEntityDescription insertNewObjectForEntityForName:@"Features" inManagedObjectContext:context];
            [featureInfo setValue:featureName forKey:@"name"];
            [featureInfo setValue:featureSecure forKey:@"secure"];
            [featureInfo setValue:featureID forKey:@"featureID"];
            [featureInfo setValue:featureSortKey forKey:@"sortKey"];
            [featureInfo setValue:featureDisplayType forKey:@"display"];
            [[featureInfo mutableSetValueForKey:@"section"] unionSet:featureSections];

            NSError *error;
            if (![context save:&error]) {
                NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
            }

            [[self.managedObjectContext objectWithID:featureDisplayType.objectID] addFeatureObject:featureInfo];
            [self.managedObjectContext save:&error];

            [featureSections removeAllObjects];


        }

        [xmlData release];
        [doc release];
        [featureSections release];

    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Features" inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];

    NSError *error;
    NSArray *featureArray = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

    [fetchRequest release];

    return featureArray;

}

UPDATE:5/25/2011

UPDATE: 5/25/2011

每个请求我发布了几个屏幕截图。

Per request I am posting a couple of screen shots.

1)这是我在所有数据被删除后加载应用程序时得到的,而且这些关系都在触摸。

1) This is what I get when the app loads after all data has been deleted and the relationships are in tact

2)是我得到当应用程序再次运行,而没有先删除和重新加载数据。底部的选项卡由其中一个实体创建,标题有点不同。发生这种情况是因为与DisplayType的关系不存在,并且它不知道要加载什么类型的视图控制器,并且不知道该选项卡要使用哪个图标。

2) This is what I get when the app runs again without first deleting and reloading data. The tabs at the bottom are created by one of the entities, and are titled a bit different. This happens because the relationship with the DisplayType is not present and it doesn't know what type of view controller to load and it doesn't know which icon to use for the tab.

推荐答案

通常,您不需要明确设置关系的两侧。当您处理一对多关系时,可能更安全的是一次向集合中添加一个实体,而不是一次设置集合。而不是:

Typically, you wouldn't need to explicitly set both sides of a relationship. When you're dealing with a to-many relationship, it's probably safer to add one entity at a time to the collection, instead of setting the collection all at once. So, instead of:

[featureInfo setValue:[NSSet setWithSet:featureSections] forKey:@"section"];

我会循环遍历 featureSections Feature 实体的关系逐个添加每个对象,例如:

I would loop through the featureSections Set and add each object one by one to the section relationship of the Feature entity, e.g.:

for (Sections *aSection in featureSections) {
    // use the automatically-generated relationship mutator         
    [featureInfo addSectionsObject:aSection];
}

我希望这有助于...

I hope this helps...

否则, Apple文档中的此部分可能感兴趣。

这篇关于核心数据实体关系在启动之间不保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆