プレゼンテーションレイヤーのキャッシングと思われるものがいくつか興味深い問題にぶつかりつつあり、他の人がこれを見ているのか、どのような対処法ができるのか不思議です。CoreAnimationがプレゼンテーションレイヤのコピーをキャッシュしているように見えるのはなぜですか?
暗黙的にアニメーション化されている独自のプロパティがいくつかあります。これが正常に動作します
@interface GOOLayer : CALayer
@property float gooValue;
@end
NSString *const kGOOLayerValueKey = @"gooValue";
@implementation GOOLayer
@dynamic gooValue;
- (id)initWithLayer:(id)layer {
if ((self = [super initWithLayer:layer])) {
id value = [layer valueForKey:kGOOLayerValueKey];
[self setValue:value forKey:kGOOLayerValueKey];
}
return self;
}
- (id<CAAction>)actionForKey:(NSString *)event {
id <CAAction> action = [super actionForKey:event];
if (action == nil && [event isEqual:kGOOLayerValueKey]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:event];
animation.fromValue = [self.presentationLayer valueForKey:event];
animation.duration = [CATransaction animationDuration];
return animation;
}
return action;
}
- (void)display {
GOOLayer *presoLayer = [self presentationLayer];
NSLog(@"Display GooValue: %f", presoLayer.gooValue);
}
+ (BOOL)needsDisplayForKey:(NSString *)key {
if ([key isEqual:kGOOLayerValueKey]) {
return YES;
}
return [super needsDisplayForKey:key];
}
ほとんどのケースでは、我々は適切な値が記録されて参照してください。私たちは、プロパティとして宣言すると、動的にそれらを合成することでこれをやっています。 は、最初のケースでは、我々は適切な暗黙のアニメーションを取得:
- (IBAction)doSomeGoo:(id)sender {
sublayer_.gooValue = random();
}
出力:第2のケースで
2012-12-19 10:10:41.440 CoreAnimation[94149:c07] Display GooValue: 1804289408.000000
2012-12-19 10:10:41.502 CoreAnimation[94149:c07] Display GooValue: 1804289408.000000
...
2012-12-19 10:10:41.739 CoreAnimation[94149:c07] Display GooValue: 898766464.000000
2012-12-19 10:10:41.757 CoreAnimation[94149:c07] Display GooValue: 846930880.000000
、私たちはアクションを無効にするので、私たちは結構です、単一の値の更新を取得する:
- (IBAction)doSomeGoo2:(id)sender {
long newValue = random();
NSLog(@"newValue = %f", (float)newValue);
[CATransaction begin];
[CATransaction setDisableActions:YES];
sublayer_.gooValue = newValue;
[CATransaction commit];
}
初回通過:
2012-12-19 10:11:16.208 CoreAnimation[94149:c07] newValue = 1714636928.000000
2012-12-19 10:11:16.209 CoreAnimation[94149:c07] Display GooValue: 1714636928.000000
通じ
セカンド時間:
2012-12-19 10:11:26.258 CoreAnimation[94149:c07] newValue = 1957747840.000000
2012-12-19 10:11:26.259 CoreAnimation[94149:c07] Display GooValue: 1957747840.000000
それは私たちが面白いです、トランザクションを実行する前に、私達はちょうど[CALayerのプレゼンテーション層]呼び出した第3のケースです:
- (IBAction)doSomeGoo3:(id)sender {
GOOLayer *presoLayer = sublayer_.presentationLayer;
long newValue = random();
NSLog(@"presoLayer.gooValue = %f newValue = %f", presoLayer.gooValue, (float)newValue);
[CATransaction begin];
[CATransaction setDisableActions:YES];
sublayer_.gooValue = newValue;
[CATransaction commit];
}
初回通過:
2012-12-19 10:12:12.505 CoreAnimation[94149:c07] presoLayer.gooValue = 1957747840.000000 newValue = 424238336.000000
2012-12-19 10:12:12.505 CoreAnimation[94149:c07] Display GooValue: 1957747840.000000
2回目:
2012-12-19 10:12:13.905 CoreAnimation[94149:c07] presoLayer.gooValue = 424238336.000000 newValue = 719885376.000000
2012-12-19 10:12:13.906 CoreAnimation[94149:c07] Display GooValue: 424238336.000000
presentationLayer呼び出しを追加すると、displayが現在の値を取得しないようになります。
これに対処する方法についての提案、または私が事を完全に誤解している場合はこれが予想される動作ですか?
感謝を完了し、更新することができ
[CATransaction setCompletionBlock:
を使用して、同様の問題を解決することができました。 [Core Animation Rendering Architecture](https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/CoreAnimationArchitecture.html#//apple_ref/doc/uid/TP40006655-SW1)の状態明示的に "アニメーションの処理中にCALayerのインスタンスに対応するプレゼンテーションレイヤーを問い合わせることができます。これは、現在のアニメーションを変更し、現在表示されている状態から新しいアニメーションを開始する場合に最も便利です。 私たちが見ていることを考えれば、これは間違っているようです。 – dmaclach
私はこの声明がまだ有効だと思います。 // displayを呼び出すと、その時点でユーザーに表示されるgooValueが出力されます。 // 前のpresentationLayerを照会する最後の例では、現在のrunloopサイクルが終了して変更がユーザーにすぐに見えなくなるまで、暗黙的なトランザクションが発生すると考えられます。 // 何かが実際にレンダリングされてユーザに提示されたとき(画面更新)には、現在のランループサイクルまたは出力の数を表示するためにテストを拡張する必要があります。 – fluidsonic