Вопросы по работе с несколькими контекстами управляемых объектов

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

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

person Stunner    schedule 13.07.2011    source источник
comment
Вы собираетесь запускать тысячи потоков / операций?   -  person TechZen    schedule 14.07.2011
comment
Да, это звучит глупо, я знаю, но это не будет все сразу, только 2 или 3 потока будут работать одновременно. Цель - получить данные с веб-сервера.   -  person Stunner    schedule 14.07.2011


Ответы (2)


Я не понимаю, как можно «сохранить все контексты управляемых объектов в памяти, а в конце перебрать их все и выполнить сохранение». Каждый MOC должен быть ограничен потоком, в котором он создан, поэтому я не понимаю, как можно эффективно циклически перебирать все MOC, не нарушая этого правила ограничения ... Но вы, вероятно, уже поняли, что ...

Я также считаю, что объединение MOC через NSManagedObjectContextDidSaveNotification является наиболее эффективным методом. Я бы даже сказал, что проще всего сохранять MOC после каждой вставки объекта (например, при импорте данных). Таким образом вы минимизируете объем каждого слияния! А поскольку слияния выполняются в памяти, они не требуют больших затрат, если они более детализированы.

person octy    schedule 13.07.2011
comment
+1 Это единственное реальное решение. Вы можете выполнить слияние на основе двух других уведомлений, но это будет очень и очень медленно. - person TechZen; 14.07.2011
comment
Спасибо за ответ. Я подумал об этом больше и думаю, что явное слияние контекстов даже не требуется, если я не хочу, чтобы данные обновлялись на других MOC, которые в настоящее время находятся в памяти, верно? И учитывая, что пока я импортирую данные, мне не нужно их немедленно обновлять, я просто не могу выполнить слияние, и когда мне нужно сослаться на новые данные, я могу выполнить выборку. Что вы думаете? Я правильно об этом думаю? - person Stunner; 14.07.2011
comment
Как вы сообщаете об изменениях между контекстами, полностью зависит от вас. Слияние изменений, скажем, с основным MOC после каждого импорта имеет то преимущество, что вам не нужно выполнять эту дополнительную выборку после завершения импорта. Кроме того, он сохраняет ваш основной MOC согласованным. Если вас это не волнует, вы можете пропустить слияние. Как я уже сказал, это полностью зависит от вас, подумайте, что имеет больше смысла для вашего конкретного случая использования. - person octy; 14.07.2011

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

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

person Alex Terente    schedule 13.07.2011
comment
Я не понимаю, как это может работать. Наличие одного и того же контекста, работающего в нескольких потоках, привело бы к остановке поезда. - person TechZen; 14.07.2011
comment
не в нескольких потоках, а в одном потоке, который создаст поток для загрузки, и после завершения одного потока просто уведомите ThreadControllrClass о том, что вы закончили с некоторыми данными или потерпели неудачу. - person Alex Terente; 14.07.2011