GCDとNSTimerのハマりどころ

  • 3
    Like
  • 0
    Comment
More than 1 year has passed since last update.

賢明な皆さんはこんなことは無いかも知れないけど、ハマったので覚え書き
内容は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を取得して、それにタイマーをフックしないとダメ。
じゃあないと、折角しかけたタイマーが、ランループ毎消失してしまって、失火する。
たったこれだけなんだけど、ハマる時はハマるので気をつけよう。