Типы параллелизма iOS5 NSManagedObjectContext и как они используются?

На данный момент литература о новых типах параллелизма NSManagedObjectContext кажется немного скудной. Помимо видеороликов с WWDC 2011 и некоторой другой информации, которую я собрал в процессе, мне все еще трудно понять, как используется каждый тип параллелизма. Ниже показано, как я интерпретирую каждый тип. Пожалуйста, поправьте меня, если я что-то неправильно понимаю.

NSConfinementConcurrencyType

Этот тип был нормой в течение последних нескольких лет. MOC экранированы от каждого потока. Таким образом, если поток A MOC хочет объединить данные из MOC потока B через сообщение о сохранении, поток A должен будет подписаться на уведомление о сохранении MOC потока B.

NSPrivateQueueConcurrencyType

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

Нсмаинкуеуеконкурренситипе

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


person Gobot    schedule 11.03.2012    source источник


Ответы (3)


Типы параллелизма очередей помогают вам управлять базовыми данными с несколькими потоками:

Для обоих типов действия выполняются только в правильной очереди, когда вы выполняете их с помощью одного из методов PerformBlock. то есть

[context performBlock:^{
    dataObject.title = @"Title";
    [context save:nil]; // Do actual error handling here
}];

Тип параллелизма частной очереди выполняет всю свою работу в фоновом потоке. Отлично подходит для обработки или диска io.

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

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

person midas06    schedule 15.03.2012

Я думаю, что ответы есть в примечании: Примечания к выпуску основных данных для Mac OS X Lion http://developer.apple.com/library/mac/#releasenotes/DataManagement/RN-CoreData/_index.html

Для NSPrivateQueueConcurrencyType я думаю, что вы не правы. Дочерний контекст, созданный с этим типом параллелизма, будет иметь свою собственную очередь. Родительский/дочерний контекст не полностью связан с потоками. Похоже, что родитель/потомок упрощает связь между контекстами. Я понимаю, что вам просто нужно сохранить изменения в дочерних контекстах, чтобы вернуть их в родительский контекст (я еще не проверял). Обычно шаблон родительского/дочернего контекста связан с шаблоном основной очереди/фоновой очереди, но это не обязательно. [EDIT] Кажется, что доступ к хранилищу (сохранение и загрузка) осуществляется через основной контекст (в основной очереди). Таким образом, выполнение фоновой выборки не является хорошим решением, так как запрос, стоящий за executeFetchRequest, всегда будет выполняться в основной очереди.

Для NSMainQueueConcurrencyType это то же самое, что и NSPrivateQueueConcurrencyType, но поскольку это связано с основной очередью, я понимаю, что вы выполняете операцию с контекстом без необходимости использования PerformBlock ; если вы находитесь в контексте основной очереди, например, в коде делегата контроллера представления (viewDidLoad и т. д.).

person FKDev    schedule 30.03.2012

midas06 пишет:

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

Я понял, что все наоборот: вы помещаете родительский контекст в основной поток, используя NSMainQueueConcurrencyType, а дочерний контекст — в фоновый поток, используя NSPrivateQueyeConcurrencyType. Я ошибся?

person Paul Heller    schedule 06.04.2012