NSTimer オブジェクトを作成したくありません。タイマーを無効にするにはどうすればよいですか? viewWillDisappear でタイマーを無効化したい。
-(void) viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
}
あ
作成したタイマーを保持する必要があります。
@interface MONObject ()
@property (nonatomic, retain) NSTimer * timerIvar;
@end
@implementation MONObject
...
- (void)viewDidLoad
{
[super viewDidLoad];
self.timerIvar = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
}
- (void)invalidateTimer
{
[self.timerIvar invalidate];
self.timerIvar = nil;
}
- (void)viewWillDisappear:(BOOL)animated
{
...
[self invalidateTimer];
}
B
別のオプションは、コールバックで渡されたタイマーを無効にすることですが、それは 内では発生しませんviewDidUnload:
。したがって、このシナリオにはまったく当てはまりません。
- (void)onTimer:(NSTimer *)pTimer
{
[pTimer invalidate];
}
タイマーをキャンセルできるようにしたい場合は、キャンセルしているタイマーを参照する必要があります。つまり、タイマーへのポインターを保持しておく必要があります。ジャスティンの回答を参照してください。
タイマーへの参照を保持するのが正しい方法ですが、完全を期すために、この-performSelector:withObject:afterDelay:
メソッドを貧乏人のタイマーとして使用することもできます。その呼び出しは、 を使用して無効にすることができます+cancelPreviousPerformRequestsWithTarget:
。サンプルコード:
- (void) viewDidLoad
{
[super viewDidLoad];
[self performSelector:@selector(timerTick) withObject:nil afterDelay:10];
}
その後:
- (void) viewWillDisappear
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[super viewWillDisappear];
}
ただし、これは適切な方法ではありません。オブジェクトに対して保留中の他の perform-selector リクエストがキャンセルされる可能性があるためです。何をキャンセルしようとしているのかを正確に把握できるように、タイマーを手元に置いておくことをお勧めします。
ちなみに、でタイマーを実行するのもおそらく悪い考え-viewDidLoad
です。ビューの読み込みは、表示されているビューとは関係なく、いつでも発生する可能性があります。
タイマーを保持したくない場合は、NSTimer オブジェクトがタイマー メソッド (この場合は onTimer:) に渡されるため、そのメソッドでタイマーがまだ必要かどうかを確認して無効にすることができます。ただし、タイマーを無効にする前にビューが戻ってきて、新しいタイマーを作成すると、問題が発生します。
断然最良の方法は、タイマーをインスタンス変数に格納することです。それは機能し、巧妙なトリックは必要ありません.6か月後には、何をしたかがわかります. 私はおそらく書くだろう
@property (readwrite, nonatomic) BOOL hasTimer;
タイマーが nil でない場合、getter は YES を返し、setter はタイマーを無効にするか、新しいタイマーを作成します。
多分この方法はあなたを助けることができます:
[self performSelector:@selector(onTimer:) withObject:nil afterDelay:10];