如何在复杂的Core Data模型中有效地访问数据

时间:2014-05-07 00:08:24

标签: ios core-data restkit nspredicate nsfetchrequest

我的Xcode项目中有一个非常复杂的Core Data模型。为简单起见,我将在这里说,我的模型包括与团队有很多关系的游戏,每个游戏都与玩家有很多关系。所有这三个实体都有自己的属性(例如gameLocation,teamScore,playerNumber等)。

我的数据库已完全填充,这要归功于Restkit对Ruby on Rails构建的网站提出的大量GET请求。所以现在,我想开始处理这些数据 - 显示和修改它。我知道这涉及获取请求和谓词,但我不知道何时何地需要执行这些提取。我可以获取游戏然后从该游戏访问与该游戏相关的所有内容吗?例如,这是我获取今天安排的所有游戏的代码:

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *desc = [NSEntityDescription entityForName:@"Game" inManagedObjectContext:self.managedObjectContext];
[request setEntity:desc];

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"time" ascending:YES];
[request setSortDescriptors:@[sort]];

/*** some code that determines the values for variables 'todaysDate' and 'tomorrowsDate' ***/

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date < %@)", todaysDate, tomorrowsDate];
[request setPredicate:predicate];

NSError *error = nil;
self.games = [self.managedObjectContext executeFetchRequest:request error:&error];

但现在呢?访问这些游戏团队的最佳方式是什么?我需要更多的提取请求还是效率低下?我尝试过类似的东西,但它看起来并不正确

Game *game1 = [self.games objectAtIndex:0];
NSMutableSet *game1Teams = [game1 mutableSetValueForKey:@"gameTeams"];

不仅是团队,还有我如何访问这些游戏的团队成绩?那些比赛的球员?等...

(也许对教程或一些示例代码的引用对我来说是一个好地方,因为我确定这是微不足道的事情)

2 个答案:

答案 0 :(得分:2)

关键词是:

&#34;我可以获取一个游戏,然后从该游戏中访问与该游戏相关的所有内容吗?&#34;

答案是&#34;是&#34;。

你遍历整个&#34;树&#34;基于单个获取请求,通过简单地引用指向实体中定义的集(或其他)的指针,并允许Core Data在需要加载各种实体时进行处理。

这对我来说没有任何意义,但是当我退出战斗时,我发现它比我想象的要容易得多。

这来自我的一个项目:

@property (nonatomic, retain) NSString * goalName;
@property (nonatomic, retain) NSData * goalPicture;
@property (nonatomic, retain) NSNumber * indexOrder;
@property (nonatomic, retain) NSNumber * wordPicture;
@property (nonatomic, retain) NSSet *item;
@property (nonatomic, retain) User *user;
@property (nonatomic, retain) NSSet *video;

就我而言,用户是树中的顶级节点,每个目标下可以有多个项目以及多个视频。

一旦我完成了给定用户的获取请求,我就可以在用户实体中使用NSSet访问该用户的目标。所以,我得到了一组目标:

NSSet *goals = userObj.goal;
Goal *g = [goals anyObject]; // for example.

然后,如果我想要项目&#34;包含&#34;在一个给定的目标内:

NSSet *items = g.items;
Item *i = [items anyObject];

等等。重要的是核心数据将有效地加载实体。如果您有10,000件物品附加到特定目标,您不必担心在实际需要之前获取这些物品......

答案 1 :(得分:1)

此链接对您有用

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html

具体而言,错误是你似乎要问的问题。就引用而言(例如,对来自团队的Player列表的引用),核心数据将不会获取整个数据集。它反而有一个叫做错误的东西。然后,当您尝试访问播放器时(例如[team.players objectAtIndex:10]或其他),CoreData将赶走并获取该对象的实际数据。

了解这一点,以及如何以及何时将对象转回故障以清理内存应该有助于回答你的问题。