iOS5 NSManagedObjectContext Типы параллелизма и как они используются? - PullRequest
12 голосов
/ 11 марта 2012

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

NSConfinementConcurrencyType

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

NSPrivateQueueConcurrencyType

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

NSMainQueueConcurrencyType

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

Ответы [ 3 ]

6 голосов
/ 16 марта 2012

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

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

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

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

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

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

2 голосов
/ 30 марта 2012

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

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

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

1 голос
/ 07 апреля 2012

midas06 написал (а):

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...