2010-08-27 4 views
4

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

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

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

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

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

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

+0

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html –

ответ

3

Несколько ключевых моментов, чтобы помнить:

  1. только доля объектов идентификаторы между нитями
  2. Использование NSManagedObjectContextDidSave уведомлений в сочетании с методом mergeChangesFromContextDidSaveNotification NSManagedObjectContext: или refreshObject: mergeChanges:
  3. Потратьте некоторое время написания код для разрешения ошибок слияния (например, сброс объекта и попытка повторного слияния и т. д.)

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

  1. NSManagedObject # changedValues ​​даст вам словарь всех измененных свойств, которые вы можете притон повторно после слияния. Перейдите через его ключи и вызовите NSManagedObject # setValue: forKey: повторно применить значения.
  2. Как упоминалось ранее, NSManagedObjectContext # refreshObject: mergeChanges: этот метод лучше всего использовать, если вы знаете, что нити не касаются каких-либо одних и тех же свойств. В некоторых случаях это гарантируется дизайном (сетевой поток обновляет временную метку и т. Д.).

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

Смежные вопросы