Is it safe to change a CALayer's attributes from a background thread?

calayer, ios, multithreading

Solution

updating the ui from any thread except the uithread is prohibited so you will have to do the following:

- (void) updateUI
{
[CATransaction lock];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[CATransaction begin];
myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath;
myLayer.bounds = theBounds;
[CATransaction commit];

[CATransaction flush];
[CATransaction setValue:(id)kCFBooleanFalse
                 forKey:kCATransactionDisableActions];
[CATransaction unlock];
}

and from the other thread

[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];

Problem

I want to do an animation that is responsive to device motion and I'd like it to remain smooth even if the UI thread is momentarily busy. The animation consists of changing a CALayer's bezier path. I've tried doing it from a secondary thread but I get occasional hangs where the main thread has a trashed stack. Is what I'm doing totally hopeless? Here's what I do in the thread: ``` [CATransaction lock]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; [CATransaction begin]; myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath; myLayer.bounds = theBounds; [CATransaction commit]; [CATransaction flush]; [CATransaction setValue:(id)kCFBooleanFalse forKey:kCATransactionDisableActions]; [CATransaction unlock]; ```

Original source