Роль координаторов файла и предъявителей

Поскольку файловая система совместно используется всеми рабочими процессами, проблемы могут произойти, когда два процесса (или два потока в том же процессе) пытаются действовать на тот же файл одновременно. Два различных процесса, действующие на тот же файл, могли бы внести изменения, который другой не ожидает, который мог привести к более серьезным проблемам как катастрофические отказы или повреждение данных. И даже в единственной программе, два потока, действующие на файл одновременно, могут повредить его и представить его неприменимый. Избегать этого типа конкуренции файла, OS X v10.7 и позже включает поддержку координаторов файла, позволяющих Вам координировать доступ к файлу безопасно между различными процессами или различными потоками.

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

Используя NSDocument и UIDocument для обработки координаторов файла и предъявителей

UIDocument класс на iOS и NSDocument класс на OS X инкапсулирует данные для пользовательского документа. Эти классы автоматически поддерживают:

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

Приложения, использующие классы документа, не должны использовать координаторов файла, когда приложение читает и пишет частные файлы в Application Support, Cache, или временные каталоги. Эти файлы считают частными.

Обеспечение безопасных операций чтения и операций записи Используя координаторов файла

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

Шаги для добавления поддержки координаторов файла к Вашему коду следующие:

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

  2. Когда Вы инициализируете свой объект предъявителя файла во время выполнения, сразу регистрируете его путем вызова addFilePresenter: метод класса NSFileCoordinator.

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

  4. В dealloc метод Вашего объекта предъявителя файла, вызовите removeFilePresenter: метод класса NSFileCoordinator не зарегистрировать его как предъявителя файла.

Выбор, который файлы контролировать с предъявителями файла

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

  • Пользовательские документы

  • Каталоги, содержащие медиа-файлы (музыка, фотографии, фильмы, и т.д.), которым управляет Ваше приложение

  • Файлы расположились на удаленных серверах

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

Реализация объектов предъявителя файла

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

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

  • Обеспечьте URL контролируемого файла или каталога. (Все предъявители файла должны сделать это путем реализации presentedItemURL свойство.)

  • Оставьте управление файла или каталога временно так, чтобы другой объект мог записать в него или читать из него.

  • Сохраните любые несохраненные изменения, прежде чем другой объект попытается читать из файла.

  • Дорожка изменяется на содержание или атрибуты файла или каталога.

  • Обновите свои структуры данных, когда файл или каталог будет перемещен или удален.

  • Предоставьте очереди отгрузки, на которой можно выполнить Ваши методы предъявителя файла.

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

Все Ваши методы предъявителя файла должны быть легкими и выполниться быстро. В случаях, где Ваш предъявитель файла реагирует на изменения (такой как в presentedItemDidChange, presentedItemDidMoveToURL:, или accommodatePresentedItemDeletionWithCompletionHandler: методы), Вы могли бы хотеть избежать включать изменения непосредственно от Вашего метода предъявителя файла. Вместо этого диспетчеризируйте блок асинхронно очереди отгрузки и обработайте изменения в более позднее время. Это позволяет Вам обработать изменения в удобстве своего приложения, не вызывая ненужные задержки координатору файла, инициировавшему изменение. Конечно, при сохранении или отказе от управления файла (такой как в relinquishPresentedItemToReader:, relinquishPresentedItemToWriter:, или savePresentedItemChangesWithCompletionHandler: методы), необходимо сразу выполнить все необходимые действия и не задержать их.

Для получения дополнительной информации о том, как реализовать методы NSFilePresenter протокол, посмотрите Ссылку на протокол NSFilePresenter.

Регистрация предъявителей файла с системой

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

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

Инициирование изменений файла с координатором файла

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

  1. Создайте экземпляр NSFileCoordinator класс.

  2. Вызовите метод экземпляра, соответствующий действию, Вы хотите взять файл или каталог:

    При вызове этих методов Вы обеспечиваете блок, чтобы сделать фактическое чтение или запись файла или каталога. Если необходимо считать или записать многократные элементы в пакете, необходимо вызвать prepareForReadingItemsAtURLs:options:writingItemsAtURLs:options:error:byAccessor: метод вместо этого и использование блок передали тому методу для координирования чтения и записи отдельных файлов. Используя тот метод для обработки пакетов файлов намного более эффективно, чем попытка считать или записать файлы индивидуально.

  3. Выпустите координатора файла объект, как только Вы сделаны.

Для получения дополнительной информации о том, как использовать методы NSFileCoordinator, посмотрите Ссылку класса NSFileCoordinator.