web-dev-qa-db-ja.com

NSTimerは止まらない

viewWillAppearメソッドが呼び出されているときに起動し、viewDidDisappearメソッドが呼び出されているときに無効にするタイマーがあります。ただし、ビューを一定量切り替えた後、タイマーは無効になった後も起動し続けます。どうしたの?

これが私のコードです:

NSTimer *timer;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f
                     target: self
                     selector:@selector( timerAction )
                     userInfo:nil
                     repeats:YES];
}

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [timer invalidate];
    timer = nil;
}

-(void) timerAction
{
    NSLog(@"timerAction");
}
22

私はそれを保持することによってタイマーへのリンクを維持するべきでした。 :)私は5か月前にこの質問をしましたが、驚くべきことに、どれだけ多くの経験を積んだかです。 :)

timer = [ [NSTimer scheduledTimerWithTimeInterval: ...] retain];
...
...
[timer invalidate];
[timer release];
38

これは絶対的な解決策です。上記のもののどれも私のために働いていなかったので、私はこれをしました、

タイマーを開始したい場所、

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO];

タイマーが呼び出すメソッド、

-(void)timerMethod
{
    // do what you need to do

    if (needs to be called again) {

        [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO];        
    }
}

お役に立てれば、

14
Mona

タイマーによって呼び出されるメソッドには、次の定義が必要です。

- (void)methodName:(NSTimer *)aTimer;

このようにして、メソッドには起動されたタイマーのインスタンスがあります。あなたがそれをしている方法では、メソッドはタイマーが無効にされたかどうかを知りません。

タイマーの初期化を次のように変更してみてください

timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f target: self selector:@selector(timerAction:) userInfo:nil repeats:YES]

と方法

-(void) timerAction:(NSTimer *)aTimer{...}

お役に立てば幸いです

6
lostInTransit
**In .h class**

@interface 
{
NSTimer * theTimer;

}


**in .m class**

//put this code where you want to calling the NSTimer function

        theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];



- (void)updateCounter:(NSTimer *)theTimer 
{

   // write your code here for counter update 

}


// put this code to Stop timer:

    [theTimer invalidate];
    theTimer = nil;
1
9to5ios

これはSwiftで私にトリックをしました

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    dispatch_async(dispatch_get_main_queue(),{ [weak self] in

        self?.idleTimer?.invalidate()
        self?.idleTimer = nil

    })

}
1
pegpeg

invalidateの-​​ doco は言う

「実行ループは、invalidateメソッドが戻る直前、または後の時点で、タイマーを削除して解放します。」

あなたは後で削除されていると思います。

0

- (void)viewWillAppear:(BOOL)animatedが再度呼び出されます。

実際、ビューを切り替えるたびに、またはモーダルビューを閉じた後に呼び出されます。基本的に、ビューが実際に画面に再表示されるときはいつでも、初めてではありません。

したがって、この場合、以前に無効にされていたとしても、タイマーは再起動されます。

0
Matjan

これは私のために働きます

dispatch_async(dispatch_get_main_queue(), ^{
    [timer invalidate];
});
0
Habib Ali

私も同じ問題を抱えていました。

タイマーがまだ実行中の場合、インスタンスの割り当てを解除できないため、呼び出す前にインスタンスを停止する必要があります。

- (void)stopTimer
{
    [timer invalidate];
    [timer release];
    timer = nil;
}

このメソッドを呼び出した後、私のタイマーは本当に停止します

0
Bruno

viewWillDisappear:でタイマーを解放するのを忘れました

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [timer invalidate];
    [timer release];
    timer = nil;
}

ただし、これによってタイマーが起動し続けることはありません...

0
rpetrich

タイマーを作成したら、それを登録してNSRunLoopCommonModesで実行します。

[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];

その後、invalidateメソッドが機能します。

0
Terry