Reputation: 32061
I know it's safe to draw on any thread so long as I call
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
UIGraphicsEndImageContext();
on the same thread.
Taking a screenshot of a view via this method takes about 300 ms, which is not bad, but I'm in a tight situation, so I want to do it in a background thread.
Here's what I'm doing:
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();
});
The only thing here in question is the view
, which lies on the main thread. Is it safe to call renderInContext
on a view.layer
from a background thread? Or generally, is it safe to read-only of a UIKit object from another thread?
(And please don't give me the default "UIKit is not thread safe" answer. I already know that. This here is a special case (and don't tell me there are no special cases).)
(the code above works fine, but I'm not sure if that's just a coincidence.)
Upvotes: 7
Views: 4325
Reputation: 43330
Core Graphics and Core Animation being low-level APIs, are generally thread safe. However, the same rules about access still apply: Any work must not be accessed by more than one thread at the same time, else drawing will fail and your app will crash. I would be wary (but not afraid) of UIImage, as UIKit objects aren't just not thread safe, they're basically ticking time bombs in background threads, and will happily dive straight off a cliff into Exception Land for no good reason. However, because UIImage is just a CGImage wrapper, again, most drawing is thread safe.
Upvotes: 8