0

13分間隔で発射するタイマーを設定しています。しかし、タイマーは不規則な間隔で起動しているようです。これは断続的な問題です。一部のユーザーからこの問題が報告されましたが、私は同じ問題を再現できません。

- (void)resetIdleTimer
{
    if (_idleTimer)
    {
        [_idleTimer invalidate];
        [_idleTimer release];
        _idleTimer = nil;
    }

    _idleTimer = [[NSTimer scheduledTimerWithTimeInterval:13*60.0
                                                   target:self
                                                 selector:@selector(idleTimerExceeded)
                                                 userInfo:nil
                                                  repeats:NO] retain];
}

- (void)idleTimerExceeded
{
        // do some processing
    [_idleTimer release];
    _idleTimer = nil;
}

条件によってはタイマーがリセット(resetIdleTimer)されますが、それでもタイマーは13分でリセットされます。

コードを調べたところ、タイマー パラメーターがセレクターに渡されていないという問題しか見つかりません。それがこの問題の理由かどうかわかりませんか? 誰かがこの種の奇妙なことに出くわしましたか? (タイマーを引数として持つようにコードを更新する方法)。1 人のユーザーは、それがちょうど 4 分後に起こったと報告しました。

4

3 に答える 3

1

タイマー パラメータをセレクタに渡さなくても、問題は発生しません。

これは正常に動作する更新されたコードです

@property(nonatomic,strong)NSTimer *myTimer;

また

 @property(nonatomic,retain)NSTimer *myTimer;

メソッド

- (void)resetIdleTimer
{

  if ([self.myTimer isValid]) 
        [self.myTimer invalidate];

   self.myTimer = [NSTimer scheduledTimerWithTimeInterval:13*60.0
                                 target:self
                               selector:@selector(idleTimerExceeded)
                               userInfo:nil
                                repeats:NO];
} 
- (void)idleTimerExceeded
{
  NSLog(@"tiggered");
}
于 2013-03-15T07:55:43.710 に答える
0

コードにエラーは見つかりません。唯一のアイデアは、ユーザーがインスタンスを作成するクラスに入り、それをインスタンス「A」と呼び、タイマーを開始し、13 分前にクラスを終了してから、もう一度入力することです。新しいインスタンス「B」を使用すると、新しいタイマーが開始されます...

この時点で、ユーザーはタイマー メソッドが 13 分後に起動することを期待しています...しかし、「A」のタイマーはまだ保留中であり (クラスを閉じる方法にエラーがある可能性があるため)、実行されます...

いくつかのログを追加して、私が言ったように実行しようとし、すべてのログを確認してください (特に、dealloc を入力し、idleTimerExceeded 印刷インスタンスのログが resetIdleTimer で印刷された最後のインスタンスと等しい場合):

    -(void)resetIdleTimer  {
            if (_idleTimer)
            {
                [_idleTimer invalidate];
                [_idleTimer release];
                _idleTimer = nil;
            }

            NSLog(@"...resetIdleTimer: instance: %p", self);
            _idleTimer = [[NSTimer scheduledTimerWithTimeInterval:13*60.0
                                                           target:self
                                                         selector:@selector(idleTimerExceeded)
                                                         userInfo:nil
                                                          repeats:NO] retain];
             NSLog(@"...resetIdleTimer: _idleTimer: %p", _idleTimer);
       }

        - (void)idleTimerExceeded
        {
                // do some processing
            NSLog(@"...idleTimerExceeded: instance: %p", self);
            NSLog(@"...idleTimerExceeded: _idleTimer: %p", _idleTimer);

            [_idleTimer release];
            _idleTimer = nil;
        }


        -(void) dealloc 
        {
            NSLog(@"...dealloc: instance: %p", self);
            [super dealloc];

        }

単なるアイデア...しかし、タイマーがパラメーターで渡されたインスタンスを保持することを忘れている可能性がありtarget:ます(「self」を渡すため、クラスインスタンスが保持されます)。そのため、一般的なエラーは、クラスインスタンスを閉じるときにタイマーを閉じるのを忘れることです.

正しい方法は次のとおりです。

-ルート クラス (AAA) がタイマーを使用してクラス (BBB) をインスタンス化する -BBB がそのタイマーを開始する -AAA が dealloc/resetIdleTimer クラス BBB を使用したい: リリースする前に BBB.timer を停止/無効化する必要があります (タイマーが BBB を保持しない場合、BBB が勝ちましたタイマーがそのメソッドを起動/実行するまで解放されません)

それで、あなたの場合は...タイマーを停止/無効にするクラスAAAから呼び出すことができるメソッドを追加します。

-(void)stopTimer{
                if (_idleTimer)
                {
                    [_idleTimer invalidate];
                    [_idleTimer release];
                    _idleTimer = nil;
                }
}
于 2013-03-15T09:19:21.083 に答える
0

タイマーを正確に 13 分で起動させたい場合は、次のようにするとよいでしょう。

https://stackoverflow.com/a/3519913/1226304

于 2013-03-15T10:37:34.527 に答える