我正在编写一个具有四个主要实体的应用程序,这些实体都通过关系链接在一起。有些是一对一的,有些是一对多的。初始加载时,三个实体从本地存储到应用程序的XML文件加载其数据,其中一个实体从Web下载XML并从中加载数据。应用加载时,它会执行检查以查看每个文件中的数据是否比当前文件中的数据更新,如果是,它将用相应文件中的数据替换该实体中的所有当前数据。
在编写过程中,作为调试过程的一部分,我一直在强制删除所有数据。调用delete函数并在应用程序启动时加载所有数据时,应用程序会很好地运行,并且所有实体和关系的行为均与预期的一样。但是,当我删除对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)这是在删除所有数据并且关系完好之后加载应用程序时得到的结果
2)这是在应用程序再次运行而无需首先删除和重新加载数据时得到的。底部的标签是由其中一个实体创建的,标题略有不同。发生这种情况是因为不存在与DisplayType的关系,并且它不知道要加载哪种类型的 View Controller ,也不知道该选项卡使用哪种图标。
最佳答案
通常,您不需要显式设置关系的双方。当您处理一对多关系时,一次将一个实体添加到集合中而不是一次全部设置集合可能更安全。因此,代替:
[featureInfo setValue:[NSSet setWithSet:featureSections] forKey:@"section"];
我将遍历
featureSections
集合并将每个对象一个一个地添加到section
实体的Feature
关系中,例如:for (Sections *aSection in featureSections) {
// use the automatically-generated relationship mutator
[featureInfo addSectionsObject:aSection];
}
我希望这有帮助...
否则,Apple文档中的this section可能会引起您的兴趣。