Используя Core Graphics / Cocoa, вы можете рисовать в растровом контексте из фонового потока? - PullRequest
9 голосов
/ 01 апреля 2009

Я рисую за пределами экрана на CGContext, созданном с использованием CGBitmapContextCreate, затем генерирую из него CGImage с помощью CGBitmapContextCreateImage и рисую его на моем виде в drawRect (я также рисую некоторые другие Кроме того, это упражнение по выделению различных уровней изменчивости и сложности).

Это все работает нормально, когда все работает в основном потоке. Однако одним из мотивов такого разделения было то, что неэкранная часть могла быть запущена в фоновом потоке (что, как я думал, должно быть в порядке, поскольку оно не отображается в экранном контексте).

Однако, когда я делаю это, изображение получается пустым! Я проверил код и разместил разумный NSLog, чтобы убедиться, что все происходит в правильном порядке.

Мой следующий шаг - свести это к простейшему коду, который воспроизводит проблему (или найти какую-то глупую вещь, которую я пропускаю, и исправить ее) - после этого у меня будет какой-то код, чтобы публиковать здесь, если это необходимо. Но сначала я хотел проверить здесь, что я не иду по неверному пути с этим. В своих путешествиях по гуглосфере я не смог найти ничего, что могло бы пролить свет в любом случае, но друг упомянул, что столкнулся с подобной проблемой, пытаясь изменить размеры изображений в фоновом потоке - предполагая, что здесь может быть какое-то общее ограничение.

[править]

Спасибо за ответы, пока. Если ничего другого, они сказали мне, что, по крайней мере, я не одинок в том, что у меня нет ответа на этот вопрос - что было частью того, что я хотел выяснить. На данный момент я собираюсь приложить дополнительную работу для получения простейшего возможного примера и, возможно, вернусь с некоторым кодом или дополнительной информацией. А пока продолжайте поступать идеи: -)

Одно замечание: пара человек использовала термин безопасность потоков в отношении API. Следует отметить, что в этом контексте существует два типа безопасности потоков:

  1. Поточность самого API - то есть может ли он вообще использоваться из более чем одного потока (глобальное состояние и другие проблемы повторного входа, такие как strtok в C, являются распространенными причинами того, что API может быть также не безопасным для потоков).
  2. Атомарность отдельных операций - могут ли несколько потоков взаимодействовать с одними и теми же объектами и ресурсами через API без блокировки на уровне приложения?

Я подозреваю, что упоминание до сих пор было первого типа, но был бы признателен, если бы вы могли уточнить.

[edit2 - решено!]

Хорошо, у меня все работает. Резюме заключается в том, что проблема была со мной, а не с самим растровым контекстом.

В моей фоновой ветке, непосредственно перед тем, как я погрузился в контекст растрового изображения, я занимался подготовкой некоторых других объектов. Оказывается, что косвенно, вызовы тех других объектов, которые приводят к вызову setNeedsDisplay для некоторых представлений! Разделив часть, которая сделала это, на основной поток, теперь все работает отлично.

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

Спасибо всем

Ответы [ 5 ]

3 голосов
/ 01 апреля 2009

Просто предположение, но если вы пытаетесь вызвать setNeedsDisplay из другого потока, вам нужно вызвать его с помощью executeSelectorOnMainThread.

2 голосов
/ 01 апреля 2009

То, что вы делаете, должно работать, если вы работаете с CGContextRef в одном-единственном потоке. Я делал это раньше с 8 ядрами, работающими над 8 различными частями изображения, а затем скомбинировал различные результирующие CGImageRef вместе и нарисовал их на экране.

1 голос
/ 01 апреля 2009

Apple ничего не говорит о безопасности потоков на iPhone, но Cocoa (в отличие от UIKit) , как правило, безопасен для потоков . Поскольку они имеют много общего кода для рисования, я бы предположил, что рисование на iPhone является потокобезопасным.

Тем не менее, ваш опыт будет означать, что есть проблемы. Может быть, вы используете свое изображение до того, как оно будет отображено?

0 голосов
/ 16 декабря 2010

На случай, если кто-то ищет / ищет именно то, как это сделать, я написал сообщение в блоге , в котором описывается, как это сделать, и все это включается в подкласс NSOperation.

0 голосов
/ 01 апреля 2009

Не все API являются поточно-ориентированными. Некоторые требуют блокировки или требуют, чтобы они выполнялись в главном потоке. Вы можете изучить документацию. Я считаю, что есть страница, которая обобщает, какие части SDK являются поточно-ориентированными, а какие - нет.

...