2012-07-06 4 views
7

Я знаю, что это безопасно рисовать на любом потоке до тех пор, как я называюНасколько безопасен этот поток кода Core Graphics?

UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
UIGraphicsEndImageContext(); 

на одной и той же теме.

Снимок экрана с помощью этого метода занимает около 300 мс, что неплохо, но я в плотной ситуации, поэтому хочу сделать это в фоновом потоке.

Вот что я делаю:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0); 
     [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
     UIImage * screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
    }); 

Единственное, здесь идет речь, является view, который лежит на главном потоке. Можно ли позвонить renderInContext на view.layer из фоновой темы? Или, вообще, безопасно ли только для чтения объект UIKit из другого потока?

(И, пожалуйста, не дайте мне по умолчанию «Ответ на вопрос UIKit is not thread safe». Я уже знаю это. Это особый случай (и не говорите мне, что особых случаев нет).)

(код выше работает отлично, но я не уверен, что это просто совпадение.)

+0

Я не думаю, что вы получите окончательный ответ на этот вопрос, потому что нигде в документации Apple не укажет ничего, кроме «UIKit is is not thread safe» (наряду с перечисленными исключениями). То, что вы получите, это мнения и опыт других людей, но, как вы сказали, приведенный выше код отлично работает, но кто должен сказать, что он всегда будет, и даже если кто-то еще скажет вам, что так оно и будет, не так ли? – Rog

+0

Действуют ли правила нитей для изменения или чтения объекта? – Snowman

+0

И что, если я сделаю копию представления раньше, так что я уверен, что я этот метод будет единственным, у которого есть доступ к этой новой копии? – Snowman

ответ

7

Core Graphics и Core Animation является API-интерфейсы низкого уровня, как правило, поточно. Тем не менее, те же правила доступа по-прежнему применяются: к любой работе не следует обращаться более чем с одним потоком одновременно, иначе рисунок не удастся, и ваше приложение выйдет из строя. Я бы опасался (но не боялся) UIImage, поскольку объекты UIKit не просто не являются потокобезопасными, они в основном тикают бомбы замедленного действия в фоновом потоке и будут счастливо нырять прямо с утеса в Исключительную Землю без уважительной причины. Однако, поскольку UIImage - это всего лишь оболочка CGImage, опять же, большинство чертежей являются потокобезопасными.

+0

Так есть ли умная альтернатива для снятия скриншота в фоновом режиме? Как насчет использования NSData в потоке bg и использования этого для создания изображения в основном потоке? – Snowman

+0

Скриншоты в фоновом режиме? Невозможно без IOSurface, которое Apple теперь довольно хорошо осознает благодаря Display Recorder, однако, если это не имеет значения, см. [Здесь] (http://stackoverflow.com/questions/11090184/how-does-the- ИОС-приложение-дисплей-рекордер запись-The-экран-без использования-частного-ар /). – CodaFi

+0

Не в фоновом режиме - фоновый поток Я имею в виду .. – Snowman

Смежные вопросы