Методы наиболее успешной практики

Инкрементные хранилища дают Вам скорость и эффективность памяти, необходимо работать с большими, сложными хранилищами данных. Можно использовать усовершенствованные методы, описанные в этой главе, чтобы улучшить и подстроить производительность и объем потребляемой памяти приложения. Стратегии ниже предназначаются и оптимизируют для определенного charactertistics Вашего формата хранения, таким образом, некоторые из этих задач смогут не примениться к Вашему приложению. Задачи в этой главе описывают методы наиболее успешной практики для использования при реализации эффективных, терпимых к отказу инкрементных хранилищ.

Кэширование и упреждающая выборка

Ваша реализация должна сбалансировать любые специальные показатели производительности Вашего хранилища с использованием памяти и сетевой пропускной способностью где применимо.

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

Если единственный, большой запрос быстрее, чем многократные, меньшие запросы, объекты пакетного запроса, а не создайте запросы частного лица каждый раз, когда отказ запущен в объект. Например, время, которое требуется для подачи с запросом к веб-сервису, обычно более длительно, чем время, которое требуется для веб-сервиса для генерации ответа.

Если запросы к Вашему запоминающему устройству являются медленными или если доступность Ваших изменений хранилища, запишите кэш в диск. В этом случае, когда Ваше хранилище получает executeRequest:withContext:error: сообщение, Ваша реализация сразу возвращает результаты кэша локального диска и одновременно инициировала выборку к Вашему хранилищу данных поддержки. Когда та выборка возвращается, обновите свой кэш локального диска и отправьте уведомление Вашему пользовательскому интерфейсу так, чтобы это знало, чтобы повторно выбрать.

Кэш строки

Кэш строки позволяет Вам осуществлять отказы сразу из памяти, а не значения перевыборки от отступающего хранилища данных на основе контекста управляемого объекта stalenessInterval или Ваше собственное предопределенное значение переутомления. Когда выполнение запроса против Вашего хранилища является дорогим, это выгодно.

С кэшем строки Вы получаете существующий узел от своего кэша и используете NSIncrementalStoreNode класс updateWithValues:version: метод для обновления значений узла. Без кэша строки Вы создаете и возвращаете новое NSIncrementalStoreNode возразите каждый раз, когда отказ запущен и Ваш newValuesForObjectWithID:withContext:error: метод вызывается. Создание инкрементного узла хранилища имеет значительные издержки, так кэширование Ваших инкрементных узлов хранилища предпочтительно.

Реализация кэша строки

Разработайте класс что кэши инкрементные узлы хранилища с метками времени извлечения и «подсчетами ссылок». Подсчет ссылок является просто целым числом, которое Вы постепенно увеличиваете каждый раз, когда контекст управляемого объекта начинает использовать объект и декремент, когда контекст управляемого объекта заканчивает использовать объект. Когда отказ запущен, и узел устарел по сравнению с интервалом переутомления контекста, повторно выберите значения и обновите узел вместо того, чтобы просто возвратить его из кэша строки. Аналогично, если подсчет ссылок достигает нуля, произведите чистку узла от своего кэша.

NSIncrementalStore обеспечивает два метода, managedObjectContextDidRegisterObjectsWithIDs: и managedObjectContextDidUnregisterObjectsWithIDs:, то, что Вы используете для отслеживания, какие управляемые объекты используются в настоящее время Базовым Стеком данных. В результате Ваше хранилище может сбросить данные, поскольку это становится неиспользованным. Ваше хранилище не должно сохранять сильные ссылки ни к каким объектам поддержки данных, использующимся — необходимо сбалансировать стоимость I/O переполучения данных со стоимостью поддержания его в памяти. Реализации по умолчанию этих методов ничего не делают; они могут быть переопределены лицами, осуществляющими внедрение хранилища так, чтобы их хранилища могли поддержать ресурсы, использующиеся и избавляющиеся от ресурсов, которые больше не необходимы.

Используя кэш строки

Когда Вы получаете запрос с типом результата NSManagedObjectResultType или NSManagedObjectIDResultType, выберите и уникальные идентификаторы и атрибуты объектов от Вашего запоминающего устройства и вставьте значения в Ваш кэш строки. Не предварительно заполняйте управляемые объекты, возвращенные как часть NSManagedObjectResultTyperesultType набор. Когда Базовые Данные дают сбой в атрибутах на Ваших управляемых объектах, Вы используете newValuesForObjectWithID:withContext:error: возвратить неистекшие выбранные с упреждением значения из Вашего кэша строки вместо того, чтобы получить записи от запоминающего устройства.

Дисковый кэш

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

Реализация дискового кэша

Назад Ваше инкрементное хранилище с NSSQLiteStoreType введите персистентное хранилище на полностью отдельном Базовом Стеке данных. Дополнительное преимущество - то, что персистентное хранилище может проанализировать и модификаторы объема и дескрипторы вида в запросе выборки на Вас. Когда Вы выбираете от отступающего хранилища данных, и затем используете в своих интересах обширный встроенный механизм парсинга запроса выборки персистентного хранилища SQLite, можно проигнорировать дескрипторы вида и определить объем модификаторов.

Используя дисковый кэш

Когда Ваше инкрементное хранилище получит запросы выборки, передайте запросы к отступающему персистентному хранилищу и возвратите результаты.

Оптимистическая блокировка

Оптимистическая блокировка является механизмом в Базовых Данных, предоставляющих персистентному координатору хранилища возможность обнаружить, когда конфликты в памяти происходят и также обрабатывают, когда Ваше инкрементное хранилище обнаруживает, что другой клиент делал изменения запоминающим устройством.

Разрешение конфликтов в памяти

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

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

Разрешение конфликтов в хранении

Когда записи в отступающем хранилище данных изменяются другим персистентным координатором хранилища или другим клиентом, конфликт в отступающем хранилище данных происходит. Обнаружение конфликтов в запоминающем устройстве является ответственностью Вашего пользовательского инкрементного хранилища.

С оптимистическими отказами блокировки встречаются при обработке запроса сохранения внутри executeRequest:withContext:error:. Для создания отчетов об оптимистическом отказе блокировки в отступающем хранилище данных создать NSMergeConflict объекты для каждого конфликтного объекта в запросе сохранения, набор параметр ошибок и возврат nil от метода. Вы не должны пытаться частично выполнить запрос сохранения. Посмотрите Ссылку класса NSMergeConflict для получения дополнительной информации.

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

Работа с веб-сервисами

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

Поточная обработка

Когда выборка и сохраняет запросы, выполняются контекстами управляемого объекта на различных потоках, персистентный координатор хранилища собирает запросы в последовательную очередь и диспетчеризирует каждый запрос единственному экземпляру Вашего инкрементного хранилища в порядке, в котором они были получены. Поскольку персистентный координатор хранилища требует, чтобы результаты были сразу возвращены (а не задержанным механизмом обратного вызова), Ваше хранилище должно синхронно возвратить данные из отступающего хранилища данных. Если Ваше хранилище данных поддержки поддерживает параллельные операции чтения и/или операции записи, поскольку оптимальная производительность рассматривает использование многократных персистентных координаторов хранилища при разработке Базового Стека данных.

Парсинг предикатов

Предикат является модификатором объема, фильтрующим результаты запроса выборки. Представленный кратким обзором NSPredicate класс, предикат составлен из левого значения, правого значения и оператора сравнения — или это составлено из двух или больше вложенных предикатов и оператора объединения. Например, age == 40 простой предикат сравнения, и (age == 40) AND (name == "Jack") простой составной предикат.

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

Для получения дополнительной информации о предикатах, см. Руководство по программированию Предиката, а также Ссылку класса NSPredicate, Ссылку класса NSCompoundPredicate, Ссылку класса NSComparisonPredicate и Ссылку класса NSExpression.