我仅使用设备收到以下警告:
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];
}
}
任何关于为什么会这样的想法,以及我如何解决这个问题?
答案 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的一些调用必须在主线程下完成,并且不能从后台线程调用。
另请注意,经过多次此类警告后,我的应用程序完全停止响应。所以最好不要忽视这样的警告。