Можно ли использовать Quartz 2D для создания UIImage на другой нити?
Я хочу переместить некоторый код, который занимает пару секунд, чтобы сгенерировать UIImage в другом потоке, но я получаю контекстную ошибку при использовании
UIGraphicsBeginImageContextWithOptions(size,false,0);
Перед вызовом диспетчера для создания образа, говорящего "недопустимый контекст 0x0" для каждой операции, которую я пытаюсь сделать. Возможно ли это вообще?
3 ответа:
Что нового в iOS: iOS 4.0 говорит это:
- рисование в графическом контексте в UIKit теперь потокобезопасно. Конкретно:
Процедуры, используемые для доступа к графическому контексту и управления им, теперь могут корректно обрабатывать контексты, находящиеся в разных потоках.
- рисование строк и изображений теперь потокобезопасно.
- теперь безопасно использовать объекты цвета и шрифта в нескольких потоках.
Похоже, вы пробовали что-то вроде этого:
UIGraphicsBeginImageContextWithOptions(size,false,0); dispatch_async(someQueue, ^{ [UIColor.whiteColor setFill]; UIRectFill(0, 0, 20, 20); dispatch_async(dispatch_get_main_queue(), ^{ UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); self.imageView.image = image; }); };
Это не сработает, потому что каждый поток имеет свой собственный стек графических контекстов (начиная с iOS 4.0). Вам нужно сделать это так:
dispatch_async(someQueue, ^{ UIGraphicsBeginImageContextWithOptions(size,false,0); [UIColor.whiteColor setFill]; UIRectFill(0, 0, 20, 20); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); dispatch_async(dispatch_get_main_queue(), ^{ self.imageView.image = image; }); };
Обновление
Документация для
UIGraphicsBeginImageContextWithOptions
и других графических функций UIKit теперь говоритВ iOS 4 и более поздних версиях вы можете вызвать эту функцию из любого потока вашего приложения.
Документация для
UIColor
говоритЦветовые объекты являются неизменяемыми, поэтому их можно безопасно использовать из нескольких потоков в приложении.Документация для
UIFont
говоритОбъекты шрифтов являются неизменяемыми, поэтому их можно безопасно использовать из нескольких потоков в приложении.
Однако , документация для UIKit
NSString
-чертежные дополнения говоритМетоды, описанные в этом расширении класса, должны использоваться из вашего основной поток приложения.
Поэтому вы должны Не попробовать что-то вроде
[@"hello" drawAtPoint:CGPointZero withAttributes:attrs]
из фонового потока.
Документы говорят:
Эту функцию следует вызывать только из основного потока приложения.
Поэтому вызывать его в другом потоке не очень хорошая идея.
Вместо этого можно попробовать использовать CoreGraphics и вызвать
CGBitmapContextCreate()
.