0

我正在使用示例库存应用程序学习 CoreData。我的数据模型有 2 个实体,“拥有”和“资产类型”。财产与称为“assetType”的资产类型具有一对一的关系,而资产类型与名为“财产”的财产具有一对多的关系。每个 Possession 只有一个 Asset Type,但 Asset Types 有多个 Possession。

我想根据资产类型将表格视图分类为多个部分。不过,我需要一些帮助来填充我的数据结构。

这是我将如何建模我的表视图控制器

表部分的 NSArray 数组中的每个部分对象将是一个 NSDictionary,其中包含 2 个键,@"Header" - 将是资产类型,@"Possessions" 是该资产类型的财产数组。

我可以处理从这个结构构建我的表格视图没有问题。我还可以处理从 CoreData 获取资产类型到我的字典的标题键中。我被难住的地方是我如何利用资产类型与财产的多对多关系,以便我可以将财产放入字典的数组中。

如何将每个资产类型的财产放入一个数组中?

我是否需要使用谓词发出获取请求以获取具有匹配资产类型的财产,还是有更简单的方法?- 似乎效率低下,因为它必须检查所有财产以进行比赛!?!?!?!?

AssetType 实体的一对多关系“拥有”是 AssetType 实体的可访问属性吗?如果是这样,我该如何访问它?它返回什么?

我不是在寻找免费代码,但如果需要,我愿意发布我的代码。我真正想要的是知道解决这个问题的最佳方法,并可能指出在线有用的信息来完成这个。我不是一个完整的新手,但我仍然无法理解 CoreData,到目前为止,Apple 文档在这个主题上仍然让我很困惑。我很感激提供的任何帮助。

4

2 回答 2

1

如果您使用 Xcode 默认的 NSManagedObject 模板创建了 AssetType 类(见图)

文件/新建/文件.../核心数据/NSManagedObject 子类

你的 AssetType.h 中应该有类似的东西:

@interface AssetType : NSManagedObject

@property (nonatomic, retain) NSSet *possessions;

@end

@interface AssetType (CoreDataGeneratedAccessors)

- (void) addPossessionsObject:    (Possession *) value;
- (void) removePossessionsObject: (Possession *) value;
- (void) addPossessions:          (NSSet *) value;
- (void) removePossessions:       (NSSet *) value

@end

所以如果你有一个 AssetType 对象,你可以通过该possessions属性访问所有与之相关的 Possession 对象。虽然默认情况下它没有排序,因此要将这些对象作为数组访问,您需要调用集合的-allObjects方法,该方法将集合中的对象作为数组返回,然后可能以某种方式对这些对象进行排序。

编辑:

此外,即使您没有以这种方式创建 NSManagedObject 子类并且它还没有possessions实现该属性,您也可以按照与上面示例中所述相同的方式将该属性添加到该类中,并在 AssetType.m 中实现它作为@dynamic possessions.

于 2012-04-11T16:26:16.320 回答
0

从我正在阅读的内容来看,我怀疑这比您想象的要容易得多。

在我看来,您已经设想在您的 UITableController 的 tableView:cellForRowAtIndexPath: 方法中使用字典数据结构,而您可能根本不需要使用它。

当您表视图控制器实例化时,(viewDidLoad: 可能是最合适的地方)只需使用如下代码检索您的资产:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Asset" inManagedObjectContext:context];
[fetchRequest setEntity:entity];

NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
    // handle errors here
}

[fetchRequest release];

如有必要,将 fetchedObjects 数组分配给 NSArray 类型的实例变量,以便您可以在管理表的 UITableViewController 类中的多个位置引用它。然后在上面的代码之后,您可以执行以下操作:

self.assets = fetchedObjects;

如果您还没有为资产 NSManagedObject 创建自定义子类,那么数组中的每个对象都是 NSManagedObject 类型,您需要将其读入该类型的变量中。

当您需要与资产相关的所有物列表时,它已经存在于数组中的每个资产对象中(这就是 CoreData 的美妙之处,如果它实际上没有在内存中实例化,那么当您尝试访问该属性时,CoreData 将自动为你实例化它)。

因此,假设您尚未为 NSManagedObject 定义自定义类,那么您的数组对象将属于该类型。将数组中的一个资产对象分配给一个名为(适当地)资产的局部变量,

例如,这会将索引 0 处的对象分配给局部变量。

NSManagedObject *asset = [self.assets objectAtIndex:0];

您可以使用以下代码获得您的财产:

NSSet *assetPossessions = [asset valueForKey:"@possessions"];

(假设在 xCode 的模型编辑器中定义的关系已被命名为“拥有”)

或者,如果您为 Asset NSManagedObject 生成了自己的自定义子类,那么这可能是一个更好的示例:

MyManagedAssetObject *asset = [self.assets objectAtIndex:0];
NSSet *assetPossessions = asset.possessions;

注意在这个例子中,我假设你没有使用 NSFetchedResultsController。实际上,使用一个表来管理一个表甚至更容易,但是就像编程的情况一样,只有当你知道“只做一件事”并且(矛盾地)使答案复杂化时,它才会变得更容易。既然你没有提到它,我假设你没有使用它。

希望这可以帮助。保罗

于 2012-04-11T16:56:54.873 回答