пятница, 11 июня 2010 г.

Quartz-рисование в отдельном потоке

Будьте заранее готовы к некоторым проблемам, если захотите рисовать что-либо в отдельном потоке. Отдельный поток для рисования сложного контента необходим для того, чтобы GUI-контролы продолжали отвечать на ваши нежные прикосновения к экрану iPhone в то время, как на экране что-то продолжает рисоваться.

Из основного потока вы можете нажать какой-либо GUI-контрол (например кнопку или слайдер). Если нужно, то можно через изменение некоторых объектов (или даже простых bool переменных) попросить поток рисования изменить параметры рисунка или что-то в этом роде.

Есть одна очень существенная деталь, которую нужно помнить!

Ну само собой, нужно защищать переменные от одновременного изменения их значений из разных потоков одновременно. Для этого существуют различные средства синхронизации, pthread-мютексы (в C/C++), @synchronized-блоки (в Objective C).

Я хотел предупредить о другом. Сейчас я столкнулся с серьёзной проблемой. Оказывается, когда вы захотите сделать контекст (в который вы рисуете что-либо) текущим с помощью вызова функции UIGraphicsPushContext (и потом вернуть всё как было с помощью функции UIGraphicsPopContext) ТО ВАЖНО ЗНАТЬ, ЧТО ЭТИ 2 ФУНКЦИИ МОЖНО ВЫЗЫВАТЬ ТОЛЬКО ИЗ ОСНОВНОГО ПОТОКА ПРОГРАММЫ!

Мне нужно рисовать в контекст (не контекст экрана, а контекст в памяти) текст. Если я не сделаю этот контекст текущим, то текст в результате не нарисуется. Проблема в том, что я должен рисовать текст в отдельном потоке рисования. Из-за этого я вынужден из этого отдельного потока просить главный поток программы делать вызовы этих 2-х функций (UIGraphicsPushContext и UIGraphicsPopContext) и ждать каждый раз пока главный поток не соизволит это сделать (а главный поток может быть занят в это время чем-то важным, как ему кажется). Это приводит к целому ряду проблем, которых можно было бы избежать, если я бы знал об этом заранее (это бы позволило предпринять некоторые меры при предварительном проектировании, ещё до того, как была написана первая строка кода). У меня сейчас даже случаются дедлоки (взаимные блокировки потоков).

Так что, дорогие мои, будьте осторожны, если захотите что-либо рисовать в отдельном потоке, учитывайте этот момент.

Комментариев нет:

Отправить комментарий

Постоянные читатели