0

シミュレータではなく、デバイスでのみ発生するように見える問題があります。

私のアプリのアニメーションは、次の方法を使用して開始および停止されます。

NSTimer* animationTimer;

-(void)startAnimation
{
    if(animationTimer == nil)
        animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}

-(void)stopAnimation
{
    [animationTimer invalidate];
    animationTimer = nil;
}

シミュレータでは、これは正常に機能し、drawViewは60fpsで呼び出され始めます。デバイス(iPod Touchでテスト中)では、scheduleTimerWithTimeIntervalメソッドが機能していないようです。さらに、[animationTimerinvalidate]はEXC_BAD_ACCESSを引き起こします。

明らかですが小さな欠陥を見つけました。stopAnimationメソッドにif(animationTimer!= nil)を追加すると、クラッシュは防止されますが、アニメーションタイマーが適切に初期化されないという問題は解決されません。

編集:上記はクラッシュを防ぐことはできません。AnimationTimer!= nilであるにもかかわらず、invalidateを呼び出すと、EXC_BAD_ACCESSが発生します。

また、この問題はデバイスで常に発生するわけではありません。たぶん40%の確率で。

4

2 に答える 2

3

あなたanimationTimerが示したとおりに宣言されている場合、その初期値は未定義です。割り当てられた Objective-C オブジェクトに対応しないポインター値をメッセージで送信すると、EXC_BAD_ACCESS. 初期値を明示的に に設定するnilか、クラスのメンバー変数として宣言してnil、オブジェクトが割り当てられるときに他のメンバー変数とともに 0/ に初期化されるようにする必要があります。

于 2010-05-08T15:37:25.070 に答える
0

タイマーはリアルタイムのメカニズムではありません。タイマーが追加された実行ループ モードの 1 つが実行中で、タイマーの起動時間が経過したかどうかを確認できる場合にのみ起動します。典型的な実行ループが管理するさまざまな入力ソースのため、タイマーの時間間隔の有効な分解能は 50 ~ 100 ミリ秒程度に制限されます。長い呼び出し中、または実行ループがタイマーを監視していないモードである間にタイマーの起動時間が発生した場合、実行ループが次にタイマーをチェックするまで、タイマーは起動しません。したがって、タイマーが潜在的に起動する実際の時間は、スケジュールされた起動時間よりもかなりの時間になる可能性があります。

NSTimer は常に「時間通り」に起動するとは限らないことに注意してください。あなたのアプリケーションはシミュレーター上で動作します。これは、Mac で利用できるほぼすべてのプロセッサと RAM という膨大な量のリソースが利用できるためです。一方、デバイスで使用できるリソースの量は限られています。これにより、アプリケーションである種の競合状態が発生する可能性があります。

もう 1 つは、タイマーを保持していないことです (これは良いことです)。そのため、所有権を主張した唯一のオブジェクトは現在の実行ループです。[タイマー無効化]を呼び出すと、次のようになります。タイマーが解除されます。[timer invalidate] によってタイマーが別の場所で解放された可能性は十分にあります。関数。すでに無効化されているタイマーを無効にしようとすると、説明に合ったエラーが発生します。

全体として、タイマーが無効になっている可能性のある他の場所をコード全体で調べます。競合状態も確認してください。

これがお役に立てば幸いです、ポール

于 2010-05-07T08:39:07.747 に答える