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

Car*_*arl 6 iphone cocoa-touch core-data objective-c ios

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

作为编写过程中调试过程的一部分,我一直在强制删除所有数据.调用delete函数并在应用程序启动时加载所有数据时,应用程序运行得非常漂亮,所有实体和关系的行为都应该完全正常.但是,当我删除对delete函数的调用并执行检查并尝试从它存储的数据运行时,所有关系似乎都消失了.在调试中,我发现所有实体都包含它们应该具有的所有常规数据,它们只是没有关系.我无法弄清楚为什么世界上的关系在第一次加载时保存但在没有重新导入所有数据时都不会保留.

我想一些代码对任何调试都有帮助,但是,我不确定我应该包括多少.因此,我将首先介绍数据加载类中调用的一个方法.如果有任何其他方法有帮助,请告诉我.很感谢任何形式的帮助.

更新的代码:2011年2月25日(基于建议 - 问题仍然存在)更新代码:2011年2月25日 - 解决问题

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

}
Run Code Online (Sandbox Code Playgroud)

更新:2011年5月25日

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

1)这是我删除所有数据并且关系完好后加载应用程序时得到的结果

数据正确加载

2)这是我在没有首先删除和重新加载数据的情况下再次运行时获得的内容.底部的选项卡由其中一个实体创建,标题略有不同.发生这种情况是因为与DisplayType的关系不存在,并且它不知道要加载哪种类型的视图控制器,并且它不知道用于选项卡的图标.

数据加载 - 关系丢失

oct*_*cty 4

通常,您不需要显式设置关系的双方。当您处理一对多关系时,一次向集合中添加一个实体可能比一次设置所有集合更安全。所以,而不是:

[featureInfo setValue:[NSSet setWithSet:featureSections] forKey:@"section"];
Run Code Online (Sandbox Code Playgroud)

我将循环遍历featureSectionsSet 并将每个对象一一添加到实体section的关系中Feature,例如:

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

我希望这有帮助...

否则,Apple 文档中的这一部分可能会引起您的兴趣。