Попытка отправить процесс в фоновый режим без блокировки пользовательского интерфейса
Я пытаюсь вызвать метод, в котором я отправляю в фон, используя dispatch_async
,
Это должно быть что-то простое, но по некоторым причинам пользовательский интерфейс все еще блокируется, пока метод не вернется.
Вот что у меня есть:
dispatch_queue_t privateQueue = dispatch_queue_create("com", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(privateQueue, ^
{
__block UIImageView *imgView = [[UIImageView alloc] initWithFrame:self.view.frame];
dispatch_async(dispatch_get_main_queue(), ^
{
imgView = [controllerB startProcess];
controllerC.imageView = imgView;
});
});
Я все еще должен ждать startProcess
возвращается до того, как пользовательский интерфейс снова станет свободным.
Затем я попытался двигаться imgView = [controllerB startProcess];
вне dispatch_get_main_queue()
:
dispatch_async(privateQueue, ^
{
__block UIImageView *imgView = [[UIImageView alloc] initWithFrame:self.view.frame];
imgView = [controllerB startProcess];
dispatch_async(dispatch_get_main_queue(), ^
{
controllerC.imageView = imgView;
});
});
В этом случае пользовательский интерфейс никогда не обновляется imgView
но пользовательский интерфейс не заблокирован.
Я пытался использовать глобальную очередь, но результат тот же (пользовательский интерфейс должен ждать):
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
Я думаю, что мне здесь не хватает чего-то очень очевидного. Либо это, либо это был долгий день для меня.
РЕДАКТИРОВАТЬ:
В [controllerB startProcess];
Я использую:
UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Я не уверен, имеют ли эти методы какое-либо отношение к GCD, что вызывает мою проблему. Изображение просто.png.
Долго думал об этом. У меня заканчиваются идеи. Единственный способ обновить пользовательский интерфейс с помощью изображения - это поместить вызов метода в dispatch_get_main_queue()
, что превосходит цель использования GCD, потому что весь пользовательский интерфейс блокируется, пока изображение не будет готово и метод не вернется.
Любое предложение будет с благодарностью.
2 ответа
Используйте второй подход. Измените startProcess для использования блоков завершения и обновите ваш imageView внутри блока завершения. Это гарантирует, что imageView обновляется после завершения startProcess.
Возможно ли, что - во втором примере - когда вы пытаетесь установить imageView в главной очереди, асинхронный расчет imageView в фоновом режиме еще не завершен, поэтому он не может отобразить imageView? В этом случае может помочь диспетчерская группа:
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("com.name.queue”, DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
//Do work
imgView = [controllerB startProcess];
});
dispatch_group_notify(group,queue,^{
//This code runs as soon as the code in the dispatch group is done.
controllerC.imageView = imgView;
});