Необходимо ли выполнять чтение базовых данных в executeBlock при использовании NSMainQueueConcurrencyType? - PullRequest
12 голосов
/ 03 апреля 2012

Согласно ответу Даниэля Эггертта в на этот вопрос , при использовании контекста управляемого объекта с NSPrivateQueueConcurrencyType необходимо сделать все, что касается или принадлежащих ему объектов внутри performBlock: или performBlockAndWait:

То же самое верно для NSMainQueueConcurrencyType? Представьте себе следующий код, работающий в главном потоке, например, в UIViewController:

self.moc = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease];
//moc setup

__block RHWidget *widget = nil;

[self.moc performBlockAndWait:^{
    widget = [(RHWidget *)[self.moc objectWithID:self.widgetObjectID] retain];
}];

self.labelView.text = widget.descriptionString;

[widget release];

Безопасно ли использовать виджет вне блока, так как мы знаем, что мы в главном потоке? Или это необходимо сделать:

__block NSString *description = nil;

[self.moc performBlockAndWait:^{
    RHWidget *widget = (RHWidget *)[self.moc objectWithID:self.widgetObjectID];
    description = [widget.descriptionString copy];
}];

self.labelView.text = description;

[description release];

Изменится ли ситуация, если есть еще один NSManagedObjectContext, возможно, типа частной очереди, выполняющий работу в блоках и передающий изменения в self.moc как parentContext?

Конечно, это немного надуманный пример, но было бы неплохо безопасно передать этот виджет, например, в контроллер модального представления, которому требуется доступ к некоторым свойствам виджета. Должен ли я вместо этого передавать objectID виджета и заново его набирать в performBlock: в новом контроллере представления?

1 Ответ

7 голосов
/ 03 апреля 2012

Обновление: Согласно Сессия 303 WWDC 2011 (Что нового в базовых данных на iOS) , NSMainQueueConcurrencyType предназначена для обеспечения нормального обмена сообщениями в главном потоке;вам нужно использовать -performBlock: только при взаимодействии с контекстом из другого потока.(Остальные релевантные части моего исходного ответа приведены ниже.)


Я создал приложение или два, которое модифицирует стандартный шаблон приложения Xcode «Master-Detail», чтобы сделать «основной» MOC (созданныйприложение делегируется и передается между контроллерами представления) только для основной очереди и родительского в контекст частной очереди, который я использую для фоновых операций, таких как импорт данных из веб-выборки.Таким образом, большинство случаев использования контекста и его объектов происходит без включения в performBlock:.(Единственный раз, когда я использую performBlock:, - это отправить изменения из контекста фоновой задачи обратно в основной для обновления пользовательского интерфейса.) Работает просто отлично.

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