Возразите пожизненному управлению

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

Роль контекста управляемого объекта

Управляемые объекты знают, с каким контекстом управляемого объекта они связаны, и контексты управляемого объекта знают, какие управляемые объекты они содержат. По умолчанию, тем не менее, ссылки между управляемым объектом и его контекстом слабы. Это означает, что в целом Вы не можете полагаться на контекст для обеспечения долговечности экземпляра управляемого объекта, и Вы не можете полагаться на существование управляемого объекта гарантировать долговечность контекста. Другими словами просто потому что Вы выбрали объект, не означает, что это останется вокруг.

Исключение к этому правилу - то, что контекст управляемого объекта поддерживает сильную ссылку любому измененному (вставленный, удаленный и обновленный) объекты, пока отложенная транзакция не фиксируется (с a save:) или отброшенный (с a reset или rollback). Обратите внимание на то, что менеджер по отмене может также сохранить сильные ссылки к измененным объектам — посмотрите управление Изменением и Отменой.

Можно изменить поведение контекста по умолчанию, таким образом, что оно действительно сохраняет сильные ссылки к своим управляемым объектам путем отправки ему a setRetainsRegisteredObjects: сообщение (с параметром YES) — это заставляет времена жизни управляемых объектов зависеть от контекста. Это может быть удобством при кэшировании меньших наборов данных в памяти — например, если контекст управляет временным набором объектов, которые могут сохраниться вне единственного цикла события, такой, редактируя в листе. Если Вы выполняете фоновую выборку и передаете идентификаторы объектов основному потоку, может также быть полезно при использовании многократных потоков и передающих данных между ними — например. Фоновый поток должен сохранить сильные ссылки к объектам, которые он выбрал с упреждением для основного потока, пока он не знает, что основной поток фактически использовал идентификаторы объектов для сбоя локальных экземпляров в себя.

Необходимо обычно использовать отдельный контейнер для хранения сильных ссылок только теми управляемыми объектами, в которых Вы действительно нуждаетесь. Можно использовать массив или словарь или объектный контроллер (например, NSArrayController экземпляр), который имеет сильные ссылки объекты, которыми он управляет. Управляемые объекты, в которых Вы не нуждаетесь, будут тогда освобождены, когда возможный (например, когда отношения очищены).

Если Вы закончили с контекстом управляемого объекта, или по некоторой другой причине Вы хотите «разъединить» контекст от его персистентного координатора хранилища, Вы не должны устанавливать координатора контекста в nil:

// This will raise an exception.
[myManagedObjectContext setPersistentStoreCoordinator:nil];

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

Повреждение циклов сильной ссылки отношения

Когда у Вас есть отношения между управляемыми объектами, каждый объект поддерживает сильную ссылку к объекту или возражает, с которым это связано. Это может вызвать циклы сильной ссылки. Чтобы гарантировать, что ссылочные циклы повреждаются, когда Вы закончены с объектом, можно использовать метод контекста управляемого объекта refreshObject:mergeChanges: превратить его в отказ.

Вы обычно используете refreshObject:mergeChanges: обновить значения свойств управляемого объекта. Если mergeChanges флаг YES, метод объединяет значения свойств объекта с теми из объекта, доступного в персистентном координаторе хранилища. Если флаг NO, однако, метод просто возвращает объект в отказ без слияния, заставляющего его повреждать сильные ссылки к связанным управляемым объектам. Это повреждает цикл сильной ссылки между тем управляемым объектом и другими управляемыми объектами.

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

Изменение и управление отменой

Контекст сохраняет сильные ссылки к управляемым объектам, имеющим незаконченные изменения (вставки, удаления или обновления), пока контекст не отправляется a save:, reset , rollback, или dealloc сообщение или надлежащее число неDOS для отмены изменения.

Менеджер по отмене, связанный с контекстом, сохраняет сильные ссылки к любым измененным управляемым объектам. По умолчанию в OS X менеджер по отмене контекста сохраняет неограниченную отмену/стек повторного выполнения. Для ограничения объема потребляемой памяти приложения необходимо удостовериться, что Вы вычищаете (использование removeAllActions) стек отмены контекста как и, когда надлежащий. Если Вы не сохраняете сильную ссылку менеджеру по отмене контекста, она освобождена с ее контекстом.

Если Вы не намереваетесь использовать функциональность отмены Базовых Данных, можно сократить требования к ресурсам приложения путем установки менеджера по отмене контекста в nil. Это может быть особенно выгодно для фоновых рабочих потоков, а также для большого импорта или пакетных обработок.