Отмена очереди отправки - PullRequest
3 голосов
/ 23 ноября 2011

Я использую Grand Central Dispatch в своем приложении для запуска метода в фоновом режиме.Метод вычисляет некоторые математические данные на основе ввода пользователя, и для этого требуется некоторое время.Имейте в виду, что он не использует Интернет.

Я запускаю этот фоновый метод "вычисления" (который является очередью отправки) всякий раз, когда загружается главное представление.Проблема заключается в том, что если пользователь переключает представления в приложении во время работы метода в фоновом режиме, приложение вылетает.

Есть ли способ «отменить» очередь / остановить запуск блока кода, когдапользователь переключает взгляды?Еще один способ думать об этом, глядя на iPhone Weather.app.Когда загружается Погода, она загружает данные в фоновом режиме, и нажатие маленькой кнопки с информацией в углу во время загрузки не приводит к сбою приложения.

Спасибо!

queue = dispatch_queue_create("com.mycompany.myqueue", 0);

dispatch_async(queue, ^{  
    //make some complicated calculations
});

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Приостановка самой очереди не поможет вам после начала выполнения блока.Но вы можете определить BOOL, называемый «отмена», с помощью спецификатора __block, а затем на соответствующих этапах вычисления (на каждой итерации или другом сегменте) вы можете проверить, что «отмена» все еще НЕТ, прежде чем продолжить.

1 голос
/ 25 ноября 2011

Другие уже предложили простую технику установки общего флага отмены (именно так следует делать отмену, поскольку GCD не поддерживает отмену неявно), но тот факт, что ваше приложение вылетает, когда пользователь переключает представления, также подразумевает, что есть работаделается внутри блока, который специально привязан к состоянию пользовательского интерфейса.Когда пользователь отключается, тот факт, что ваш фоновый блок становится смертельно запутанным из-за этого, наводит на мысль, что вам действительно нужно несколько реорганизовать код.Вы уже должны отправлять все вызовы AppKit или UIKit в основной очереди, поскольку они не будут работать ни от каких других, поэтому должна существовать ссылка на объект, которая изменяется, когда пользователь переключает представления, и вам просто нужно учесть это дляслучай, когда операция была немедленно отменена после вашей проверки на нее, и вы все еще стремитесь завершить взаимодействие с пользователем до предела.GCD снимает с вас много бремени многопоточного кода, но это не панацея от проблем параллелизма, таких как ссылки на общие объекты и т. Д. - они все еще остаются и являются трудными проблемами, GCD просто делает их гораздо проще исправить (например, позволяет вам создать соответствующую последовательную очередь для каждого разделяемого / утверждаемого объекта в вашем коде и рефакторизовать ваши методы setter / getter для использования этой очереди в качестве барьера параллелизма).

...