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 に答える