Ken Aspeslagh немного неверен в отношении рисования вторичных потоков (он прав, как правило, это плохая идея). Из того, что я вижу в вашем коде, у вас нет хорошего варианта для рисования на вторичном потоке. Можете ли вы объяснить, почему вы хотите это сделать?
Вы сами уже обнаружили setCanDrawConcurrently:
, в котором явно говорится о вызове drawRect:
из фонового потока. Обратите внимание, что для окна просмотра должно быть установлено значение allowsConcurrentViewDrawing
для YES (это значение по умолчанию).
Apples own Cocoa Drawing Guide имеет раздел на чертеже из вторичных резьб. Я выделил некоторые части, которые, я думаю, имеют отношение к вам.
В комплекте приложений для каждого окна и комбинации потоков используется уникальный графический контекст. Поскольку каждый поток имеет свой собственный объект контекста графики для данного окна, можно использовать вторичные потоки для рисования в этом окне. Однако есть некоторые оговорки.
Во время обычного цикла обновления для окон все запросы на рисование отправляются в основной поток приложения для обработки. Обычный цикл обновления происходит, когда пользовательское событие вызывает изменение в вашем пользовательском интерфейсе. В этой ситуации вы вызываете метод setNeedsDisplay: или setNeedsDisplayInRect: (или семейство методов отображения) из основного потока приложения, чтобы аннулировать части вашего представления, которые требуют перерисовки. Вы не должны вызывать эти методы из любых вторичных потоков.
Если вы хотите обновить окно или просмотр из вторичного потока, вы должны вручную заблокировать фокус на окне или просмотреть и инициировать рисование самостоятельно. Фокусировка блокировки настраивает среду рисования для графического контекста этого окна. После блокировки вы можете настроить среду рисования, выдать команды рисования как обычно, а затем очистить содержимое графического контекста до буфера окна.
Для того, чтобы делать рисунки регулярно на дополнительной резьбе, вы должны уведомить об этом себя.. Самый простой способ отправки регулярных уведомлений - использовать объект NSTimer или NSAnimation. Для получения дополнительной информации о том, как оживить содержание в разделе «Методы Advanced черчения.»
The Cocoa Threading Programming Guide также говорит, что это:
Если вы хотите использовать нить, чтобы привлечь к виду, скобка все рисование код между методами lockFocusIfCanDraw и unlockFocus из NSView
Просто в стороне, НОД блок вызов, вероятно, гораздо лучше, способ для выполнения небольших наборов операций в фоновом режиме, чем NSThread
.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// you can put each of these calls in their own queue if you want
[self DrawText];
[self DrawRectangle];
[self DrawGradient];
});
Однако, это, вероятно, не имеет ничего общего с вашей проблемой; Я упоминаю об этом только потому, что думаю, что вам будет лучше использовать очереди GCD.
Интересно! Благодаря! –
Важное примечание: установка 'canDrawConcurrently' на' YES' означает, что ** 'drawRect:' сам будет вызываться в фоновом потоке. ** Вам не нужно и не следует, а затем вызывать несколько других методов рисования в других потоках а затем вернуться. –
@PeterHosey ты уверен? docs говорят, что «можно вызвать в фоновом потоке», а не «будет» –