Можно ли другим потокам иметь косвенный доступ к контексту управляемого объекта, работающему в собственном потоке? - PullRequest
3 голосов
/ 30 сентября 2010

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

Хотя я могу себе представить, что это хорошо, например. читатель RSS, для некоторых приложений это кажется далеко от идеала. В моем случае я пишу музыкальный секвенсор, который записывает и воспроизводит данные, используя фоновый поток. Мне нужно, чтобы записанные данные были доступны для основного потока во время записи / воспроизведения. Необходимость постоянно сохранять и загружать данные во время записи / воспроизведения была бы достаточно плохой, но, хуже того, казалось бы, вынуждает пользователя сохранять при каждой записи или воспроизведении, что как бы выкрикивает «ужасное приложение».

Однако, похоже, что есть способ обойти это. Если другим потокам не нужен доступ к самим основным объектам данных (только к данным, которые они содержат), что мешает мне запускать контекст управляемого объекта в своем собственном потоке и разрешать только другим потокам косвенный доступ, например, посредством привязки пользовательского интерфейса объекты к свойству, которое вызывает performSelector:onThread:withObject:waitUntilDone: в потоке контекста управляемого объекта для получения / установки значений?

Это не дает некоторых преимуществ многопоточности (то есть масштабирование данных ядра для многоядерных процессоров), но в большинстве случаев нам просто нужно, чтобы многопоточность не блокировала пользовательский интерфейс, когда происходит что-то интенсивное.

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

1 Ответ

2 голосов
/ 01 октября 2010

Вы не можете контролировать детали реализации внутренних объектов NSManagedObject, и, в частности, есть причины, по которым CoreData может потребоваться что-то делать в контексте, когда вы читаете атрибут.

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

Вы можете использовать executeSelector: on * Thread: если хотите, но тогда вы будете иметь дело с проблемами синхронизации, задержкой и другими забавными моментами параллелизма.Лично я бы пошел с механизмом очередей, описанным выше.

...