Ошибка в основных данных и выборка для множества отношений - PullRequest
7 голосов
/ 17 февраля 2012

У меня есть несколько «теоретических» вопросов о поведении базовых данных, связанных с тем, что происходит с отношением «ко-многим», и когда полагаться на обход отношения от родительского объекта, и когда должен быть построен новый запрос на выборку. Они все очень связаны.

Фон

Предположим, родительский объект RPBook, который имеет отношение ко-многим к RPChapter. Книга имеет много глав. Обратное задано и в базовой модели данных. Используется базовая форма упорядоченных вручную отношений, поэтому у сущности RPChapter есть свойство chapterIndex. Я не использую новые упорядоченные отношения iOS5 здесь (также не относящиеся к этим вопросам).

Чтобы добраться до глав в книге, можно использовать аксессор отношений chapters:

RPBook *myBook; // Assume this is already set to an existing RPBook
NSSet *myChapters = myBook.chapters

Использование / Настройка

В приложении для iPhone мы начинаем с табличного представления со списком RPBook экземпляров. Соответствующие главы не будут предварительно извлечены как часть спецификации извлечения для контроллера извлеченных результатов, поддерживающего представление таблицы, поскольку эти главы еще не нужны.

Теперь я выбираю один из этих RPBook экземпляров, я перехожу на новую страницу, и у меня есть эта ссылка на экземпляр RPBook в моем контроллере представления, для которого НЕ chapters предварительно выбрана.

Вопрос 1: Вызвать filteredSetUsingPredicate: на chapters отношение сразу

Если я захочу фильтровать через отношение chapters, используя filteredSetUsingPredicate: напрямую, будет ли это работать даже надежно, учитывая, что я не извлек предварительно все связанные RPChapter экземпляры текущего RPBook I'm смотря на? Другими словами, filteredSetUsingPredicate: вызывает сбой за кулисами всех объектов в этом отношении, чтобы выполнить свою задачу, или он будет вводить в заблуждение только результаты, основанные на том, какая из глав уже была в памяти (если есть) ?

Если у меня нет вопиющего количества связанных глав с книгой, должен ли я вместо этого стилизовать это, сначала вызвав allObjects? т.е.

[[self.chapters allObjects] filteredArrayUsingPredicate:predicate]

вместо просто:

[self.chapters filteredSetUsingPredicate:predicate]

Вопрос 2: Пакетный поиск всех глав книги

В случае, если у меня есть экземпляр RPBook, но нет связанных с ним предварительно извлеченных RPChapter экземпляров, как заставить все главы книги быть извлеченными за один снимок, используя отношение chapters? [myBook.chapters allObjects] делает это, или я все еще могу получить ошибки от этого вызова?

Я хочу, чтобы базовые данные выполняли все ошибки в пакете, а не отключали ошибки для нечетного RPChapter, запрашиваемого, если это повлияет на поведение использования filteredSetUsingPredicate: в отношении chapters, как указано в вопросе 1 выше .

Должен ли я обратиться к явному запросу на выборку, чтобы сделать это? Должен ли я повторно получить RPBook, который у меня уже есть, но на этот раз запросить в запросе на выборку, чтобы все связанные главы также были получены с помощью setRelationshipKeyPathsForPrefetching:?

Этот последний вариант мне просто кажется расточительным, потому что у меня уже есть область видимости, представляющая концептуально подмножество всех RPChapter экземпляров, которые меня интересуют. Как можно больше, я бы хотел просто пройтись по графу объектов.

Вопрос 3: NSFetchedResultsController экземпляров RPChapter в одном потоке

Настройка В этом случае у меня есть экземпляр RPBook, но нет предварительно извлеченных экземпляров RPChapter, связанных с ним (но они существуют в Магазине). В том же контроллере представления у меня также есть экземпляры NSFetchedResultsController (FRC) из RPChapter, относящиеся к той же книге. Так что это тот же поток, тот же контекст управляемого объекта.

Является ли экземпляр RPChapter из FRC тем же объектом в памяти, что и экземпляр RPChapter экземпляра, который я извлекаю из myBook.chapters, который имеет тот же ObjectID? Иными словами, исполняет ли среда выполнения когда-либо запросы управляемых объектов для одного и того же ObjectID от того же MOC в том же потоке, используя различные физические объекты в памяти?

Вопрос 4. Шаблон проектирования установки NSFetchedResultsController внутри управляемого объекта для обслуживания запросов для отношения

Я пытаюсь решить, смогу ли я обслуживать запросы об отношениях, содержание которых часто меняется (главы в моем примере в книге), используя встроенное отношение chapters, предоставленное в моем пользовательском RPChapterПодкласс управляемого объекта или, если это вообще нормально с точки зрения дизайна / архитектуры, для установки FRC из RPChapter экземпляров в класс RPBook управляемого объекта для эффективного обслуживания запросов о главах в этой книге.

Совершенно ясно, если бы я мог просто положиться на аксессор chapters в экземпляре myBook, но кажется, что FRC здесь может быть более производительным и эффективным в ситуациях, когда большой объем целевых объектов в отношении ко-многимСуществуют.

Является ли это излишним или это справедливое использование FRC для запроса RPBook о его главах по-разному?Почему-то кажется, что я упускаю возможность просто пройтись по графу объектов.Я хотел бы иметь возможность доверять , что отношение chapters всегда актуально, когда я загружаю свой экземпляр RPBook.

1 Ответ

10 голосов
/ 17 февраля 2012

Вопрос 1

Да, это будет работать. Когда вы звоните [book chapters], устройство автоматически заполняется. Когда вы отфильтруете эти объекты, в них произойдет сбой.

Однако вы должны использовать NSFetchedResultsController здесь с предикатом, похожим на @ "book ==% @", вместо того, чтобы захватывать массив.

Вопрос 2

Лучший способ заставить NSManagedObjectContext загрузить все главы - это сделать NSFetchRequest и настроить NSFetchRequest для возврата полностью реализованных объектов вместо ошибок. Это предварительно загрузит их всех за один раз. Однако, если у вас нет TON глав, вы не получите здесь большой экономии.

Почему?

Потому что, когда вы запрашиваете эти главы, даже в ошибочном состоянии, Core Data собирается загрузить данные в кеш (исключая несколько крайних случаев, таких как двоичные данные), так что, когда вы «ошибаетесь» в объекте, это просто указатели перемещение в памяти и отсутствие дополнительного обращения к диску.

Возможно, вам понадобятся тысячи глав, чтобы увидеть какую-либо выгоду от предварительной выборки.

Вопрос 3

Да. Они будут одним и тем же объектом. NSManagedObject Экземпляры всегда будут совместно использоваться при получении из того же NSManagedObjectContext. Это часть работы NSManagedObjectContext

Вопрос 4

Вы хотите использовать NSFetchedResultsControler, это его работа. Управление этими вещами вручную является расточительным и почти гарантированно менее эффективным, чем реализация Core Data.

Однако отношение будет всегда актуальным, если вы не настраиваете его из другого потока. Так что, если вы не ожидаете обновления, вы можете просто использовать массив. Я бы не стал.

...