简体   繁体   English

核心数据实体关系在启动之间不保存

[英]Core Data Entity Relationship Does Not Save Between Launches

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.在初始加载时,三个实体从本地存储的 XML 文件加载其数据到应用程序,其中一个实体从 web 下载 XML 并从中加载其数据。 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.当应用程序加载时,它会检查每个文件中的数据是否比当前拥有的数据更新,如果是,它将用相应文件中的数据替换该实体中的所有当前数据。

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.当调用 delete function 并在应用程序启动时加载所有数据时,应用程序运行良好,所有实体和关系的行为都完全正常。 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.但是,当我删除对删除 function 的调用并执行检查并尝试从其存储的数据中运行时,所有关系似乎都消失了。 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.因此,我将首先包含在数据加载 class 中调用的方法之一。 If anything else would help, please let me know.如果还有什么可以帮助的,请告诉我。 Any help is very much appreciated.很感谢任何形式的帮助。

UPDATED CODE: 2/25/11 (Based on Suggestions - Problem still exists) UPDATED CODE: 2/25/11 - Problem Solved更新代码:2/25/11(基于建议 - 问题仍然存在) 更新代码:2/25/11 - 问题已解决

- (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更新:2011 年 5 月 25 日

Per request I am posting a couple of screen shots.根据要求,我发布了几个屏幕截图。

1) This is what I get when the app loads after all data has been deleted and the relationships are in tact 1)这是在删除所有数据并且关系完好无损后加载应用程序时得到的结果

正确加载数据

2) This is what I get when the app runs again without first deleting and reloading data. 2)这就是当应用程序再次运行而没有首先删除和重新加载数据时我得到的。 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.发生这种情况是因为与 DisplayType 的关系不存在并且它不知道要加载哪种类型的视图 controller 并且它不知道要为选项卡使用哪个图标。

已加载数据 - 缺少关系

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"];

I would loop through the featureSections Set and add each object one by one to the section relationship of the Feature entity, eg:我将遍历featureSections Set 并将每个 object 一个一个添加到Feature实体的section关系中,例如:

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

I hope this helps...我希望这有帮助...

Otherwise, this section in the Apple documentation might be of interest.否则,Apple 文档中的这一部分可能会引起您的兴趣。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM