3

我想做一个响应设备运动的动画,即使 UI 线程暂时繁忙,我也希望它保持流畅。动画包括更改 CALayer 的贝塞尔路径。我尝试过从辅助线程执行此操作,但我偶尔会在主线程有一个废弃堆栈的地方挂起。我正在做的事情完全没有希望吗?这是我在线程中所做的:

[CATransaction lock];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[CATransaction begin];
myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath;
myLayer.bounds = theBounds;
[CATransaction commit];

[CATransaction flush];
[CATransaction setValue:(id)kCFBooleanFalse
                 forKey:kCATransactionDisableActions];
[CATransaction unlock];
4

2 回答 2

4

这是我的版本。

dispatch_async(dispatch_get_main_queue(), ^{
            myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath;
            myLayer.bounds = theBounds;
        });

调度队列的优势在于能够从本地范围中拉入变量,而不必担心实现中间数据结构。

于 2012-06-01T23:33:20.553 回答
3

禁止从除 uithread 之外的任何线程更新 ui,因此您必须执行以下操作:

- (void) updateUI
{
[CATransaction lock];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[CATransaction begin];
myLayer.path = [UIBezierPath bezierPathWithOvalInRect:theRect].CGPath;
myLayer.bounds = theBounds;
[CATransaction commit];

[CATransaction flush];
[CATransaction setValue:(id)kCFBooleanFalse
                 forKey:kCATransactionDisableActions];
[CATransaction unlock];
}

并从另一个线程

[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
于 2012-06-01T22:07:25.403 回答