iOS. Приемы программирования
Шрифт:
Другой тип отношений, которые, возможно, потребуется реализовать, называется «многие ко многим». По сравнению с отношением Manager к Employee при отношении «многие ко многим» один менеджер может иметь N сотрудников, а каждый сотрудник может подчиняться N менеджерам. Чтобы организовать такие отношения, выполните те же инструкции, что и при создании отношения «один ко многим», но выделите сущность Employee, а потом отношение manager. Измените это название на managers и установите флажок To-Many Relationship (Отношение ко многим) (рис. 16.19). Теперь стрелка будет заострена с обоих концов.
Рис. 16.19.
Теперь, открыв файл Employee.h, вы увидите, что его содержимое изменилось:
Как видите, свойство managers сущности Person теперь представляет собой множество. Поскольку отношение сотрудника к его менеджерам — это множество и такое же отношение существует между менеджером и сотрудниками, здесь мы имеем пример отношения «многие ко многим»
В коде, написанном для отношения «один ко многим», можно просто создать новый управляемый объект Manager (о том, как вставлять объекты в контекст управляемых объектов, рассказано в разделе 16.3), сохранить его в контексте управляемых объектов, а потом соединить с парой управляемых объектов Employee — и их тоже сохранить в контексте. Теперь, чтобы ассоциировать менеджера с сотрудником, задайте в качестве значения для свойства FKEmployeeToManager, относящегося к экземпляру Employee, экземпляр управляемого объекта Manager. После этого фреймворк Core Data сам создаст необходимое отношение.
Если потребуется получить всех сотрудников (типа Employee), ассоциированных с объектом-менеджером (типа Manager), нужно будет просто воспользоваться методом экземпляра allObjects, относящимся к свойству FKManagerToEmployees вашего объекта-менеджера. Это объект типа NSSet, поэтому можно применить метод экземпляра allObjects, чтобы получить массив всех объектов-сотрудников, ассоциированных с конкретным объектом-менеджером.
16.9. Выборка данных в фоновом режиме
Постановка задачи
Требуется выполнять операции выборки данных в стеке Core Data, причем только в фоновом режиме. Это отличная возможность создать по-настоящему отзывчивый пользовательский интерфейс.
Решение
Перед тем как заниматься выборкой данных в фоновом режиме, создайте новый контекст управляемых объектов с параллелизмом
Обсуждение
Выборка объектов в основном потоке — не самая хорошая идея. Выполнять ее в главном потоке можно лишь в случаях, когда в стеке Core Data совсем немного элементов. Дело в том, что при операции выборки в Core Data обычно выполняется поисковый вызов. Затем этот вызов должен выбрать для вас определенные данные, обычно с помощью предиката. Чтобы сделать пользовательский интерфейс более отзывчивым, лучше всего выполнять такие операции выборки в фоновом контексте.
Вы можете создать в приложении столько контекстов, сколько захотите, однако помните об одном железном правиле. Нельзя передавать управляемые объекты между контекстами в разных потоках, так как объекты не являются потокобезопасными. Таким образом, если вы выбираете объекты в фоновом контексте, то не можете использовать их в главном потоке. Вот как следует передавать управляемые объекты между потоками: объект выбирается в фоновом потоке, а потом переносится в главный контекст (контекст, работающий в основном потоке). Это делается с помощью метода objectWithID: главного контекста. Этот метод принимает объект типа NSManagedObjectID. Поэтому в фоновом потоке мы на самом деле не выбираем управляемые объекты как таковые, а лишь берем их сохраняемые ID, после чего передаем эти ID главному контексту, который сам получает для вас управляемый объект. Итак, вы выполняете в фоновом режиме и поиск, и выборку объектов, затем передаете ID найденных объектов главному контексту. Получением самих объектов занимается уже главный контекст. Если действовать таким образом, главный контекст будет располагать сохраняемыми ID объектов, а получение этих объектов из постоянного хранилища в такой ситуации протекает гораздо быстрее, чем при выполнении полномасштабного поиска в главном контексте.
В этом разделе предполагается, что вы уже создали модель управляемых объектов Person. Подобная модель показана на рис. 16.20.
Рис. 16.20. Простая модель Core Data, используемая в этом разделе
При работе с этой моделью я заполню стек 1000 объектов Person, как показано в следующем коде, а уже потом попробую выбирать информацию из стека: