UI 操作と競合しないスレッドによるタイマー表示2012年07月21日 11:22

画面にUIPickerと、NSTimerを使ったタイマーを配置した場合、カウント中にピッカーを回転させるとその間カウンターの表示が停止する。これは、NSTimer、UIViewの表示がともにメインスレッドで動作するからです。
これを回避するには、タイマーのカウント部分を別のスレッドにすることですが、カウンターの更新部分はUI にアクセスすることになる( ...メインスレッドに用意したメソッドを呼び出す)あまりすっきりしない。iOS 4 から導入されたGCDならメインのUI にアクセスできるから扱いやすい。これを直接利用してもよいが、NSOperationQue もGCDが使われるようになっているからこれを使ってテストしてみたが、動作は快適である。

// タイマーの更新(テストコード)
- (void) countUpdate
{
 NSOperationQueue *queue = [[[NSOperationQueue alloc]init] autorelease];
 [queue addOperationWithBlock:^{

  while (1) {
   NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
   [mainQueue addOperationWithBlock:^{
    // カウントアップ
    count_++;
    // 再生時間を更新
    countLabel_.text = [NSString stringWithFormat:@"%d", count_];
   }];
   [NSThread sleepForTimeInterval:1.0f];
  }
 }];
}

参考:
 詳解 iOS 5 プログラミング