CoreAnimation警告删除线程与未提交的CATransaction
我遇到以下警告的问题:
CoreAnimation:警告,删除线程与未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以logging回溯。
我正在使用一个NSOperation对象来执行一些计算,一旦完成它发送消息回到AppDelegate,然后隐藏进度条,并取消隐藏一些button。 如果我将消息注释回AppDelegate,警告消失,但进度条显然保持可见和animation状态。
我正在使用xCode 4.4.1和OSX 10.8.1,但是,当我在OSX 10.7.4上使用相同版本的xCode编译和运行代码时,我没有得到警告,代码按预期运行。
设置CA_DEBUG_TRANSACTIONS = 1环境variables显示来自AppDelegate中的NSControl setEnabled消息的回溯。
答案可能是在面对我,但也许我有太多的咖啡!
你的怀疑是对的。 如果NSOperation在CoreAnimation完成之前完成,那么你会得到一个很好的警告:
* CoreAnimation:警告,删除线程与未提交的CATransaction; 在环境中设置CA_DEBUG_TRANSACTIONS = 1以logging回溯。*
在某些情况下,当在队列上派发的块从CoreAnimation触发一些工作并在CoreAnimation完成之前返回时,也会发生这种情况。
我使用的解决scheme很简单:在CoreAnimation上请求工作的块或NSOperation中,检查退出之前确实已完成工作。
为了给你一个概念validation的例子,这是一个在调度队列上调度的块。 为了避免这个警告,我们在退出前检查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); } }
为了与标准Cocoa范例保持一致,这里推荐的解决scheme是在主线程上执行Core Animation工作,可以使用GCD轻松完成:
dispatch_async(dispatch_get_main_queue(), ^{ [self.delegate redrawSomething]; });
通常情况下,在不期望的上下文中调用对象的方式很糟糕,所以一个好的经验法则是在向外部模块传递消息时总是将调度分派到主线程上。
一些框架,比如核心位置(Core Location),如果从主线程以外的任何上下文中调用它们,都会发出日志消息。 其他人会发出神秘的信息,比如你在这里的核心animation。
如Numist所描述的,确保任何UI绘图的另一种方法是使用方法performSelectorOnMainThread:withObject:waitUntilDone:
或者执行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. }
有关dispatch_async()
和performSelectorOnMainThread:withObjects:waitUntilDone:
之间区别的相关文章,请参阅主队列上performSelectorOnMainThread和dispatch_async之间的区别是什么?