Ошибка в основных данных и выборка для множества отношений
У меня есть несколько "теоретических" вопросов о поведении Core Data, связанных с тем, что происходит с отношением "ко-многим", и когда полагаться на обход отношения от родительского объекта, и когда должен быть построен новый запрос на выборку. Они все очень связаны.
Фон
Предположим, родительский объект 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
Я смотрю? Другими словами 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 ответ
Вопрос 1
Да, это будет работать. Когда вы звоните [book chapters]
набор будет заполнен автоматически. Когда вы отфильтруете эти объекты, в них произойдет сбой.
Тем не менее, вы должны использовать NSFetchedResultsController
здесь с предикатом что-то вроде @"book == %@" вместо захвата массива.
вопрос 2
Лучший способ заставить NSManagedObjectContext
загрузить все главы будет делать NSFetchRequest
и настроить NSFetchRequest
вернуть полностью реализованные объекты вместо неисправностей. Это предварительно загрузит их всех за один раз. Однако, если у вас нет ТОННЫ глав, вы не получите здесь много сбережений.
Зачем?
Потому что, когда вы запрашиваете эти главы, даже в сбойном состоянии, Core Data загружает данные в кеш (исключая несколько крайних случаев, таких как двоичные данные), так что когда вы "ошибаетесь" в объекте, это просто указатели, перемещающиеся в памяти и без дополнительного попадания диска.
Возможно, вам понадобятся тысячи глав, чтобы увидеть какую-либо пользу от предварительной выборки.
Вопрос 3
Да. Они будут одним и тем же объектом. NSManagedObject
экземпляры всегда будут общими при получении из одного и того же NSManagedObjectContext
, Это часть работы NSManagedObjectContext
Вопрос 4
Вы хотите использовать NSFetchedResultsControler
это его работа. Управление этими вещами вручную расточительно и почти гарантированно будет менее эффективным, чем реализация Core Data.
Однако отношения всегда будут актуальными, если вы не настраиваете их из другого потока. Так что, если вы не ожидаете обновления, вы можете просто использовать массив. Я бы не стал.