Как эффективно получить доступ к данным в сложной базовой модели данных

У меня есть довольно сложная модель Core Data в моем проекте XCode. Для простоты я просто скажу здесь, что моя модель включает в себя Игры, которые имеют отношение ко многим с командами, каждая из которых имеет отношение ко многим игрокам. Все три из этих объектов также имеют свои собственные свойства (например, gameLocation, teamScore, playerNumber и т. Д.).

Моя база данных полностью заполнена благодаря массовому GET-запросу, сделанному Restkit на сайт, созданный на Ruby on Rails. Итак, теперь я хочу начать работать с этими данными - отображать и изменять их. Я знаю, что это включает запросы на выборку и предикаты, но я не знаю, когда и где мне нужно выполнить эти выборки. Могу ли я получить игру, а затем получить доступ ко всему, что связано с этой игрой, из этой игры? Например, вот мой код для загрузки всех игр, запланированных на сегодня:

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 ответа

Решение

Ключевая фраза такова:

"Могу ли я получить игру, а затем получить доступ ко всему, что связано с этой игрой, из этой игры?"

Ответ - "Да".

Вы пересекаете все "дерево" на основе одного запроса выборки, просто ссылаясь на указатели на наборы (или что-то еще), которые определены в ваших сущностях, и позволяете 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.

Затем, если я хочу, чтобы элементы "содержались" в заданной цели:

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

и так далее. Важно то, что основные данные будут эффективно загружать объекты. Если у вас есть 10000 предметов, прикрепленных к определенной цели, вам не нужно беспокоиться о том, что их заберут, пока они действительно не понадобятся...

Эта ссылка будет полезна для вас

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

В частности, вы, похоже, спрашиваете об ошибке. С точки зрения ссылок (например, ссылки на список Игрока из Команды) основные данные не будут извлекать весь набор данных. Вместо этого есть вещь, называемая ошибкой. Когда вы затем попытаетесь получить доступ к плееру (например, [team.players objectAtIndex:10] или что-то еще), CoreData ускользнет и извлечет фактические данные для этого объекта.

Понимание этого, а также того, как и когда можно превратить объект в ошибку для очистки памяти, должно помочь вам ответить на ваш вопрос.

Другие вопросы по тегам