核心动画警告:“未提交的CATransaction”

时间:2013-01-02 10:41:47

标签: iphone ios core-animation quartz-core catransaction

我仅使用设备收到以下警告:

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

我在堆栈顶部的方法如下:

- (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];
}
}

任何关于为什么会这样的想法,以及我如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

看起来orangeGradient:是从后台线程调用的。 Core Animation将所有更改分组到CATransactions中。通常这是从运行循环自动完成的。在后台线程上(通常)没有运行循环,因此您必须自己创建事务:

- (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];
    }
}

还有另一个问题:UIKit不是线程安全的。您无法在后台主题上的bounds上致电UILabel

答案 1 :(得分:0)

在代码中的任意位置检查 未提交 CATransaction。您需要按照以下方式执行此操作;

[CATransaction begin];
[CATransaction setDisableActions:YES];
[commonClassObject orangeGradient:lblFill];
[CATransaction commit];

[编辑]

基本上,在CoreAnimation完成执行之前NSOperation完成时会发生此问题。在你的代码中的某个地方,这两个类之间必定存在某种关系,你需要弄明白这一点。

答案 2 :(得分:0)

我只想补充一点,我在后台线程中遇到了与initWithFrame相同的问题。

似乎自iOS 7及更高版本起,对UIKit的一些调用必须在主线程下完成,并且不能从后台线程调用。

另请注意,经过多次此类警告后,我的应用程序完全停止响应。所以最好不要忽视这样的警告。