2

皆さんこんにちは、ちょっとした質問です。

私がUIView作成したクラスがありAnimatedUIViewます。init で、次のようにアニメーション化するサブビューを作成します。

   - (void)animateView{
    [UIView animateWithDuration:4.0
                     delay:1.0
                     options: nil
                     animations:^{ 
                         // Animation PART 1
                         } 
                     completion:^(BOOL  completed){
                       [UIView animateWithDuration:4.0
                           animations:^{ 
                               // Animation PART 2
                               } 
                           completion:^(BOOL  completed){
                             [self animateView];
                           }
                         ];
                     }
     ]; 

}

[self animateView]最初のアニメーションだけを 1 秒遅らせたいので、オプション repeat を使用するのではなく、2 番目の完了ブロックで自分自身を呼び出す必要があります。

すべてが正常に機能し、ビューを割り当てて初期化し、サブビューとして追加すると、必要に応じてアニメーション化されます。

しかし、スーパービューを閉じると、ARC が機能し、animatedView の割り当てを解除すると思いますが、CPU は 100% 使用されます。調査したところ、 への呼び出しにコメントすると[self animateView]、スーパービューを閉じても CPU が急増しません。

だから私は問題を解決することができました(呼び出しの前に条件を置き、スーパービューを閉じる前にブール値を変更することによってkeepAnimating = NO)、なぜそれがこれを行うのかを理解したかったのですか?アニメーションを続けようとするのはなぜですか? また、CPU を大量に使用するのはなぜですか? 完了ブロックに NSLog を配置すると、最初は 8 秒ごとに表示されますが、スーパービューを閉じると、NSLog はミリ秒ごとに表示され続けます...

ところで:それはこの質問に関連しています:UIView animation using 90%CPU、実際には答えられませんでした。どうもありがとう!

4

3 に答える 3

5

CPU が 100% になると、ほぼ常に無限再帰を意味します。

アニメーションのソース コードの内容を知っているのは Apple だけなので、推測することしかできません。

この場合、これは、アニメーションが実行できなくなったときにアニメーションをトリガーしたことが原因である可能性があると思います (たとえば、dealloc状態にあるためレイヤーがありません)。これは、完了ハンドラーがすぐに呼び出され、無限再帰につながることを意味します。

無限のアニメーションを作成するより安全な方法があります (例:CAAnimationレイヤーでの使用)。

于 2013-11-12T12:07:05.993 に答える
3

ブロック内で self を使用しないでください。保持サイクルを作成します。self を呼び出す必要がある場合は、weak self ポインターを作成します。このようなコード

__weak typeof(self) weakself = self;
[UIView animateWithDuration:4.0
                     delay:1.0
                     options: nil
                     animations:^{ 
                         // Animation PART 1
                         } 
                     completion:^(BOOL  completed){
                       [UIView animateWithDuration:4.0
                           animations:^{ 
                               // Animation PART 2
                               } 
                           completion:^(BOOL  completed){
                             [weakself animateView];
                           }
                         ];
                     }
     ];

しかし、コードの主な問題は、基本ケースなしで animateView を再帰的に呼び出すことです。だから私はCPUサイクルを消費しています...ベースケースなしでanimateViewを使用しないでください。

于 2013-11-12T09:20:50.390 に答える
1

タイマーを使ってみる

viewDidLoadアニメーションを開始したい場所から、あなたまたは他の場所に次の行を書きます。

[NSTimer scheduledTimerWithTimeInterval:9 target:self selector:@selector(animateView) userInfo:nil repeats:YES];
// 9 is total animation duration.....

animateView メソッドを次のように更新します。

- (void)animateView{
    [UIView animateWithDuration:4.0
                     delay:1.0
                     options: nil
                     animations:^{ 
                         // Animation PART 1
                         } 
                     completion:^(BOOL  completed){
                       [UIView animateWithDuration:4.0
                           animations:^{ 
                               // Animation PART 2
                               } 
                           completion:^(BOOL  completed){

                           }
                         ];
                     }
     ]; 

}
于 2013-11-12T09:19:16.660 に答える