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

标签 iphone objective-c cocoa-touch ios core-data

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

作为我在写作期间调试过程的一部分,我一直在强制删除所有数据。当调用删除函数并在应用程序启动时加载所有数据时,应用程序运行良好,所有实体和关系都按照应有的方式运行。但是,当我删除对 delete 函数的调用并执行检查并尝试从它存储的数据运行时,所有关系似乎都消失了。在调试过程中,我发现所有实体都包含它们应该包含的所有常规数据,只是它们不再具有关系。我不明白为什么在第一次加载时保存关系,但在所有数据未重新导入时不保留关系。

我想一些代码对任何人调试都有帮助,但是,我不确定我应该包括多少。因此,我将首先包括在数据加载类中调用的方法之一。如果还有其他帮助,请告诉我。非常感谢任何帮助。

更新代码: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;

}

更新:2011 年 5 月 25 日

根据要求,我发布了几个屏幕截图。

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

Data Loaded Properly

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

Data Loaded - Relationships Missing

最佳答案

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

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

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

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

我希望这有助于...

否则,this section Apple 文档中的内容可能会引起您的兴趣。

关于iphone - 核心数据实体关系不会在启动之间保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6112575/

相关文章:

ios - 在 Swift 中结合 CGBitmapInfo 和 CGI​​mageAlphaInfo

iphone - 使用#pragma 消息时如何禁用警告?

iphone - 多值url通讯录iphone

ios - 如何在 UITextField 中禁止特殊字符但允许亚洲/中东字符

iPhone以编程方式读取代理设置

objective-c - NSString drawAtPoint - 模糊

ios - 为 iOS 清洁 C++ OpenGL

iphone - Obj-C,如何删除之前设置的本地推送通知?

iphone - Apple 推送通知,如何正确导出我的证书?

iphone - 如何在iphone 的iCarousel 上设置CustomFrame?