У меня есть метод, который порой может быть вызван во всем моем коде. Ниже приведен очень простой пример, поскольку код обрабатывает изображения и файлы с фотогалереи iphone и маркирует их уже обработанными, когда это делается с помощью метода.Последовательная очередь GCD, похоже, не выполняется серийно
@property (nonatomic, assign) dispatch_queue_t serialQueue;
....
-(void)processImages
{
dispatch_async(self.serialQueue, ^{
//block to process images
NSLog(@"In processImages");
....
NSLog(@"Done with processImages");
});
}
Я думаю, что каждый раз, когда этот метод называется я хотел бы получить ниже выходной ... «В processImages» «Сделано с processImages» «В processImages» «Совершено с processImages» и т.д. ...
, но я всегда получаю
"в processImages" "в processImages" "Сделано с processImages" «Сделано с процессом Изображения " etc ...
Я думал, что последовательная очередь будет ждать, пока первый блок не будет выполнен, а затем запустите. Для меня, похоже, он запускает метод, затем он снова вызывается и запускается до того, как первый вызов даже закончится, создавая дубликаты изображений, которые обычно не обрабатываются из-за того, что если он действительно будет выполняться серийно, этот метод будет знать, что они были уже обработаны. Возможно, мое понимание серийных очередей не является конкретным. Любой вход? Спасибо.
EDIT: БОЛЬШЕ Контекст ниже, это то, что происходит в блоке ... Может ли это вызвать проблему ???
@property (nonatomic, assign) dispatch_queue_t serialQueue;
....
-(void)processImages
{
dispatch_async(self.serialQueue, ^{
//library is a reference to ALAssetsLibrary object
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
....
//Process the photos here
}];
failureBlock:^(NSError *error) { NSLog(@"Error loading images from library");
}];
});
}
-(id)init
{
self = [super init];
if(self)
{
_serialQueue = dispatch_queue_create("com.image.queue",NULL);
}
return self;
}
этот объект создается только один раз, и, насколько я могу сказать, никогда не может быть создан снова основаны от моего кода ... Я буду запускать тесты, чтобы убедиться, что, хотя.
UPDATE 2: ЧТО ДУМАЮ ПРОИСХОДИТ, прокомментируйте, пожалуйста, если вы согласны/не согласны ....
Очевидно, что моя главная проблема в том, что он, кажется, этот блок кода выполняется одновременно, создавая повторяющиеся записи (дважды импортировать одну и ту же фотографию), когда это обычно не делалось, если бы оно запускалось серийно. Когда фото обрабатывается, к нему применяется «грязный» бит, который при следующем вызове метода пропускает это изображение, но этого не происходит, а некоторые изображения обрабатываются дважды. Может ли это быть связано с тем, что я перечисляю объекты во второй очереди, используя enumerategroupswithtypes: внутри этого serialQueue?
- processImages вызова
- enumerateObjects
- немедленно вернуться из enumerateObjects, так как это асинхронная себя
- отбой в processImages
processImages не реально сделано, хотя из-за того, что enumerategroups является вероятно, все еще работает, но очередь может быть выполнена, так как она доходит до конца блока до того, как enumerategroups завершили работу. Это кажется мне возможностью?
Интересно, если вы случайно вызова 'dispatch_queue_create' несколько раз. Возможно, там есть инструкция 'NSLog'. Ваши ожидания верны (что он должен быть строго последовательным), но есть что-то еще простое. – Rob
без лишнего контекста, трудно ответить, но ваше предположение верно. Интересно, используете ли вы несколько объектов, у которых есть свои очереди. Убедитесь, что ваша очередь - это общий доступ ко всем. Попробуйте распечатать текущий поток и значение serialQueue в NSLogs. –
Можете ли вы установить точку останова на вызов 'dispatch_async' и проверить, что' serialQueue' является тем же самым объектом каждый раз, когда вызывается 'processImages'. Кажется, что ваша очередь воссоздана. –