Mil*_*lly 37 multithreading core-animation nsoperation catransaction
我遇到以下警告问题:
CoreAnimation:警告,删除线程与未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以记录回溯.
我正在使用NSOperation对象来执行一些计算,一旦完成,它会将消息发送回AppDelegate,然后隐藏进度条并取消隐藏某些按钮.如果我将消息注释回AppDelegate,则警告消失,但进度条显然仍然可见且动画.
我正在使用xCode 4.4.1和OSX 10.8.1,但是,当我在OSX 10.7.4上使用相同版本的xCode编译和运行代码时,我没有收到警告,代码按预期运行.
设置CA_DEBUG_TRANSACTIONS = 1环境变量会将回溯显示为来自AppDelegate中的NSControl setEnabled消息.
答案可能是盯着我看,但也许我喝的咖啡太多了!
num*_*ist 24
为了与标准的Cocoa范例保持一致,这里推荐的解决方案是在主线程上执行Core Animation工作,使用GCD轻松完成:
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate redrawSomething];
});
Run Code Online (Sandbox Code Playgroud)
通常,在不期望的上下文中调用对象的形式很差,因此一个好的经验法则是在向外部模块传递消息时始终调度到主线程.
某些框架(如Core Location-with)如果从主线程以外的任何上下文调用它们,则会发出一条日志消息.其他人会发出神秘的消息,例如你的核心动画示例.
Jea*_*ean 19
你的怀疑是正确的.如果在CoreAnimation完成执行之前NSOperation完成,那么你会得到一个很好的警告:
*CoreAnimation:警告,删除线程与未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以记录回溯.*
在某些情况下,当在队列上调度的块触发CoreAnimation中的某些工作并在CoreAnimation完成之前返回时,也会发生这种情况.
我使用的解决方案很简单:在从CoreAnimation请求工作的块或NSOperation上,我在退出之前检查工作是否确实已完成.
为了给您一个概念验证示例,这是一个要在调度队列上调度的块.为了避免警告,我们在退出之前检查CoreAnimation是否已完成.
^{
// 1. Creating a completion indicator
BOOL __block animationHasCompleted = NO;
// 2. Requesting core animation do do some work. Using animator for instance.
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
[[object animator] perform-a-nice-animation];
} completionHandler:^{
animationHasCompleted = YES;
}];
// 3. Doing other stuff…
…
// 4. Waiting for core animation to complete before exiting
while (animationHasCompleted == NO)
{
usleep(10000);
}
}
Run Code Online (Sandbox Code Playgroud)
如Numist所描述的,确保在主线程上发生任何UI绘制的另一种方式是使用该方法performSelectorOnMainThread:withObject:waitUntilDone:
或者替代地performSelectorOnMainThread:withObject:waitUntilDone:modes:
- (void) someMethod
{
[...]
// Perform all drawing/UI updates on the main thread.
[self performSelectorOnMainThread:@selector(myCustomDrawing:)
withObject:myCustomData
waitUntilDone:YES];
[...]
}
- (void) myCustomDrawing:(id)myCustomData
{
// Perform any drawing/UI updates here.
}
Run Code Online (Sandbox Code Playgroud)
对于相关帖子之间的区别dispatch_async()
和performSelectorOnMainThread:withObjects:waitUntilDone:
看看主队列上的performSelectorOnMainThread和dispatch_async之间有什么区别?