Нужно ли делать чтение основных данных в режиме выполнения при использовании NSMainQueueConcurrencyType?
По словам Даниэля Эггерт, ответьте на этот вопрос, при использовании контекста управляемого объекта с 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
?
Это, конечно, немного надуманный пример, но было бы неплохо безопасно передать этот виджет, например, для модального контроллера представлений, которому необходимо получить доступ к некоторым свойствам виджета. Должен ли я передавать идентификатор объекта widget вместо этого и повторять его в performBlock:
в новом контроллере представления?
Ответы
Ответ 1
Обновление: Согласно WWDC 2011 Сессия 303 (что нового в основных данных на iOS), NSMainQueueConcurrencyType
предназначена для нормального обмен сообщениями по основной теме; вам нужно использовать -performBlock:
при взаимодействии с контекстом из другого потока. (Все еще важные части моего первоначального ответа ниже.)
Я сделал приложение или два, которые изменяют шаблон приложения "Мастер-Детс" по умолчанию для Xcode, чтобы сделать основной "MOC" (созданный делегатом приложения и переданный между контроллерами представлений) только для основной очереди и родительский контекст частной очереди, который я использую для фоновых операций, таких как импорт данных из веб-выборки. Таким образом, большинство применений контекста и его объектов происходит без обертывания в performBlock:
. (Единственный раз, когда я использую performBlock:
, - это переместить изменения из контекста фоновой задачи обратно в основной, чтобы обновить пользовательский интерфейс.) Работает нормально.