iphoneioscore-animationquartz-corecatransaction

Core Animation Warning: "uncommitted CATransaction"


I am getting the following warning with Device only:

CoreAnimation: warning, deleted thread with uncommitted CATransaction; created by:
0   QuartzCore                          0x3763c65d <redacted> + 220
1   QuartzCore                          0x3763c541 <redacted> + 224
2   QuartzCore                          0x3763fe2f <redacted> + 30
3   QuartzCore                          0x3763b9bf <redacted> + 318
4   QuartzCore                          0x3763b87b <redacted> + 50
5   QuartzCore                          0x3763b80b <redacted> + 538
6   MyApp                              0x000df597 -[CommonClass orangeGradient:] + 382
7   MyApp                              0x000f70e1 -[HomeViewController updateStatusBar] + 1700
8   MyApp                              0x000f61bd -[HomeViewController statusRecieved] + 224
9   MyApp                              0x000cd323 -[CommonClass statusReceivedFromServer] + 142
10  MyApp                              0x000d833d -[CommonClass accountStatus] + 7416
11  Foundation                          0x35a3767d <redacted> + 972
12  libsystem_c.dylib                   0x35c9a311 <redacted> + 308
13  libsystem_c.dylib                   0x35c9a1d8 thread_start + 8

My Method that is on top of the stack is as follows:

- (void)orangeGradient: (UILabel *)fillLabel {
@synchronized([CommonClass class]) {
CAGradientLayer * gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = fillLabel.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[UIColorFromRGB(0xfbb250) CGColor],(id)[UIColorFromRGB(0xf47c2a) CGColor], nil];
[fillLabel.layer addSublayer:gradientLayer];
}
}

Any idea on why is this coming, and how I can fix this?


Solution

  • It looks like orangeGradient: is called from a background thread. Core Animation groups all changes into CATransactions. Usually this is done automatically from the run loop. On background threads there is (usually) no run loop, so you have to create the transaction yourself:

    - (void)orangeGradient: (UILabel *)fillLabel {
        @synchronized([CommonClass class]) {
            [CATransaction begin];
            CAGradientLayer * gradientLayer = [CAGradientLayer layer];
            gradientLayer.frame = fillLabel.bounds;
            gradientLayer.colors = [NSArray arrayWithObjects:(id)[UIColorFromRGB(0xfbb250) CGColor],(id)[UIColorFromRGB(0xf47c2a) CGColor], nil];
            [fillLabel.layer addSublayer:gradientLayer];
            [CATransaction commit];
        }
    }
    

    There's another issue: UIKit is not thread safe. You can't call bounds on a UILabel on a background thread.