Я использую MagicalRecord, и в одном из контроллеров моего представления источник данных питается данными, поступающими в базу данных. Поскольку процесс подачи включает несколько этапов, я попытался использовать GCD для ускорения всего процесса. Общий процесс выглядит так.MagicalRecord и dispatch_group
Работы, которые необходимо выполнить после получения доступа к свойствам в globalSummary. Проблема в том, что приложение зависает в dispatch_group_wait. Я попытался добавить работу к шагу, и он работает в начале, но поскольку я добавляю больше работы, он работает, если я иду шаг за шагом через код, но не работает, если я позволю ему запустить.
Что-то не так с подходом или оно конфликтует с MagicalRecord в некотором роде?
- (NSArray *)dataSource
{
if (_dataSource == nil) {
_dataSource = [NSMutableArray array];
NSManagedObjectContext *privateContext = [NSManagedObjectContext contextWithStoreCoordinator:[NSPersistentStoreCoordinator defaultStoreCoordinator]];
GlobalSummary *globalSummary = [GlobalSummary insertInManagedObjectContext:privateContext]; // holds a bunch of fetched properties
dispatch_queue_t queue = dispatch_queue_create("de.berndrabe.dataSource", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t outerGroup = dispatch_group_create();
__block SectionInfo *siPilotAircraft = nil;
if ([PilotAircraft countOfEntities]) {
dispatch_group_async(outerGroup, queue, ^{
NSArray *frPilotAircraft = [PilotAircraft findAll];
// do some processing an set SectionInfo variable
});
}
__block SectionInfo *siMedicals = nil;
if ([PilotMedical countOfEntities]) {
dispatch_group_async(outerGroup, queue, ^{
NSArray *frPilotMedical = [PilotMedical findAll];
});
}
// more working packets following the same patter
dispatch_group_wait(outerGroup, DISPATCH_TIME_FOREVER);
if (siPilotAircraft.countOfRows) {
[_dataSource addObject:siPilotAircraft];
}
if (siMedicals.countOfRows) {
[_dataSource addObject:siMedicals];
}
}
return _dataSource;
}
EDIT: Использование [Entity findAllInContext:privateContext]
позволяет извлечет запись мне нужна, но она все еще теперь я застряла, когда доступ к неисправным отношениям в одном субъекте :(
Можете ли вы фактически подтвердить, что 'performBlock:' будет выполнять данные блоки параллельно по отношению к другим блокам? Боюсь, они запускаются сериализованными. Кроме того, небольшое улучшение было бы сделать 'prepareDataSource:' асинхронным, имеющий блок завершения, который вызывается, когда все асинхронные задачи (executeBlock :) завершены. dispatch_group_wait без необходимости приводит к блокировке вызывающего потока до тех пор, пока все задачи не будут завершены. – CouchDeveloper
Как утверждает Apple в своей документации, это асинхронный вызов, поэтому он немедленно возвращается. Тем не менее он помещает блок в свою приватную очередь и (я думаю) сделает все возможное, чтобы сделать работу максимально быстрой. Но поскольку это может включать в себя доступ к базе данных, он может быть сериализован. В последнем пункте, о котором вы говорили (group_wait ...), этого я хотел достичь. Мне нужно было полностью настроить объект dataSource, прежде чем я начну использовать его. –