В iOS 5 у NSManagedObjectContext
есть пара новых методов, performBlock:
и performBlockAndWait:
. Для чего на самом деле используются эти методы? Что они заменяют в старых версиях? Какие блоки должны быть переданы им? Как решить, что использовать? Если у кого-то есть примеры их использования, было бы здорово.
Для чего используется PerformBlock: NSManagedObjectContext?
Ответы (2)
Методы performBlock:
и performBlockAndWait:
используются для отправки сообщений вашему экземпляру NSManagedObjectContext
, если MOC был инициализирован с помощью NSPrivateQueueConcurrencyType
или NSMainQueueConcurrencyType
. Если вы делаете что-либо с одним из этих типов контекста, например, устанавливаете постоянное хранилище или сохраняете изменения, вы делаете это в блоке.
performBlock:
добавит блок в резервную очередь и запланирует его запуск в собственном потоке. Блок вернется немедленно. Вы можете использовать это для длительных операций сохранения в резервном хранилище.
performBlockAndWait:
также добавит блок в резервную очередь и запланирует его запуск в собственном потоке. Однако блок не вернется, пока блок не завершит выполнение. Если вы не можете двигаться дальше, пока не узнаете, прошла ли операция успешно, то это ваш выбор.
Например:
__block NSError *error = nil;
[context performBlockAndWait:^{
myManagedData.field = @"Hello";
[context save:&error];
}];
if (error) {
// handle the error.
}
Обратите внимание: поскольку я сделал performBlockAndWait:
, я могу получить доступ к ошибке за пределами блока. performBlock:
потребует другого подхода.
Из примечаний к выпуску основных данных iOS 5 :
NSManagedObjectContext теперь обеспечивает структурированную поддержку параллельных операций. Когда вы создаете контекст управляемого объекта с помощью initWithConcurrencyType:, у вас есть три варианта ассоциации его потока (очереди).
Ограничение (NSConfinementConcurrencyType).
Это значение по умолчанию. Вы обещаете, что контекст не будет использоваться никаким потоком, кроме того, в котором вы его создали. (Это точно такое же требование к многопоточности, которое вы использовали в предыдущих выпусках.)
Частная очередь (NSPrivateQueueConcurrencyType).
Контекст создает и управляет частной очередью. Вместо того, чтобы создавать и управлять потоком или очередью, с которой связан контекст, здесь контекст владеет очередью и управляет всеми деталями для вас (при условии, что вы используете блочные методы, как описано ниже).
Основная очередь (NSMainQueueConcurrencyType).
Контекст связан с основной очередью и, как таковой, привязан к циклу обработки событий приложения, но в остальном он подобен контексту на основе частной очереди. Этот тип очереди используется для контекстов, связанных с контроллерами и объектами пользовательского интерфейса, которые требуется использовать только в основном потоке.
performBlockAndWait:
не блокирует основной поток, не так ли? Сбивает с толку то, что его можно присоединить к основному циклу выполнения, но у него есть имя, из-за которого кажется, что оно заставляет вас ждать.
- person nevan king; 11.04.2012
performBlock
или performBlockAndWait
или я могу сделать так же, как раньше?
- person Fábio Oliveira; 15.04.2013
-performBlockAndWait:
не вернется, пока ^{block}
не завершит выполнение. Она ведет себя так же, как и любая старая добрая вложенная подпрограмма. Его выполнение является синхронным.
- person SwiftArchitect; 11.04.2014
performBlock
или только в часть сохранения?
- person Bigood; 13.10.2015
Они позволяют вам получить доступ к одним и тем же managedObjectContext
потокам.
Я не совсем уверен, что я прав, но я использую это так.
Вы используете performBlockAndWait
как "обычный". Вам это не нужно, если вы выполняете manageObjectContext только в одном потоке. Если вы выполняете его во многих потоках, тогда да, вам понадобится performBlock
.
Итак, если вы находитесь в основном потоке, вам не нужно делать performBlockAndWait
для основного managedObjectContext
. По крайней мере у меня нет и у меня все хорошо.
Однако, если вы получите доступ к этому managedObjectContext
в других потоках, тогда да, вам нужно будет сделать performBlockAndWait
.
Такова цель performBlock
и performBlockAndWait
.
Кто-нибудь, пожалуйста, поправьте меня, если я ошибаюсь здесь. Конечно, если вы получаете доступ к контексту только в одном потоке, вы можете просто использовать значение по умолчанию.
NSManagedObjectContext
: Core Data uses thread (or serialized queue) confinement to protect managed objects and managed object contexts. A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method. You should not, therefore, initialize a context on one thread then pass it to a different thread.
Таким образом, NSManagedObjectContexts
НЕ являются потокобезопасными, и вы не можете получить к ним доступ через потоки.
- person JRG-Developer; 05.04.2013
synchronous
или asynchronous
). См. Ответ от @MikeG и соответствующие комментарии для обсуждения этого вопроса.
- person JRG-Developer; 05.04.2013
NSManagedObjectContexts
между потоками. Чего вы не можете сделать, так это передать NSManagedObjects
между потоками. Вы можете сказать своему контексту в основном потоке, чтобы сохранить, выполнив [mainContext performBlock:^{ NSError *error = nil; [mainContext save:&error]; };
из другого потока.
- person Fábio Oliveira; 15.04.2013
performBlockAndWait:
запускается в потоке контекста, как и performBlock:
, но заставляет поток вызывающего абонента ждать завершения выполнения блока.
- person tonytony; 06.12.2013
po [NSThread currentThread]
в отладчике внутри и снаружи вызова performBlockAndWait:
и... О, это действительно выполняется в потоке вызывающего. Спасибо за ссылку.
- person tonytony; 08.12.2013