Попытка отправить процесс в фоновый режим без блокировки пользовательского интерфейса

Я пытаюсь вызвать метод, в котором я отправляю в фон, используя 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;
});
Другие вопросы по тегам