7
votes

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.)

1
I don't think you will get a definitive answer to this question because nowhere in the documentation Apple will state anything other than UIKit is is not thread safe (along with the listed exceptions). What you will get are opinions and experiences from other people but as you said, the code above works fine but who's to say that it always will and even if someone else tells you that it will, will it? - Rog
Do threading rules apply to modifying or reading an object as well? - Snowman
And what if I make a copy of the view before, so that I'm sure I'm this method would be the only one that has access to this new copy? - Snowman

1 Answers

7
votes

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.