LoginSignup
2

More than 5 years have passed since last update.

GCDとNSTimerのハマりどころ

Posted at

賢明な皆さんはこんなことは無いかも知れないけど、ハマったので覚え書き
内容はNSTimerがどんなに頑張っても発火しないという現象。
タイトルでお察しかも知れないが、GCDを使っている時にNSTimerを使う時は、ちょっと注意が必要

gcd_asyncの先でTimerの仕掛け方

気がついてしまえば当たり前なんだけど、dispatch_asyncでの処理は、新しいRunLoopが作られ、使い終わったら破棄される。これがすっぽり抜け落ちていた。

間違ったコード

wrong.m
NSTimer *aTimer = [[NSTimer alloc] initWithFireDate:date interval:seconds target:self selector:@selector(foo:) userInfo:userInfo repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer];

何が間違いかお解りだろうか?
そう!別スレッドにいるにもかかわらず、[NSRunLoop currentRunLoop]を使ってしまっている.

正解はこう

work.m
NSTimer *aTimer = [[NSTimer alloc] initWithFireDate:date interval:seconds target:self selector:@selector(foo:) userInfo:userInfo repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer];

別にmainRunLoopじゃなくてもいいんだけど、永続しているRunLoopを取得して、それにタイマーをフックしないとダメ。
じゃあないと、折角しかけたタイマーが、ランループ毎消失してしまって、失火する。
たったこれだけなんだけど、ハマる時はハマるので気をつけよう。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2