2

私は自分のゲームをNSTimer. 多くの人が私と同様の問題を抱えているのを見てきましたが、何かについて少し説明が必要です.

基本的にNSTimer、時間を表す画像を更新しているメインスレッドで実行していますが、mapView もあります。ユーザーがマップをパンすると、タイマーがブロックされます。私の質問は、新しいスレッドを作成してタイマーをその実行ループに追加した場合、セレクター (UI を更新する) を実行すると、タイマー スレッドが再びブロックされないのでしょうか? また、セカンダリ スレッドから UI を更新するのは悪い習慣であることもわかっています。

更新:両方が同じ実行ループで実行されていたため、mapView がタイマーをブロックしていたと思います。独自の実行ループを持つタイマースレッドでこれを修正しましたが、これにより2番目の問題が発生し、非常に行き詰まりました!! これがコードです...

//called when I need to restart the timer
[NSThread detachNewThreadSelector:@selector(resumeTimer) toTarget:self withObject:nil];  


-(void) restartTimer {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    timer=[NSTimerscheduledTimerWithTimeInterval:1.
                                          target:self
                                        selector:@selector(dim)
                                        userInfo:nil
                                         repeats:YES];

    [self performSelectorOnMainThread:@selector(timerImageUpdate)
                           withObject:nil
                        waitUntilDone:NO];

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];

    [pool drain];
}

このコードにより、[プールのドレイン] で Bad_access エラーが発生します

計測器でコードを実行しましたが、エラーが発生する理由がわかりません。何か案は?

4

1 に答える 1

2

タイマー用のスレッドを作成する場合でも、メイン スレッドで UI の更新を行う必要があります。performSelectorOnMainThread:withObject:waitUntilDone: NOでそれを行うことができます。これは、タイマー スレッドをブロックすることなく、メイン スレッドでメソッド呼び出しをキューに入れます。

ただし、メイン スレッドの実行ループがマップのパンによってブロックされている場合 (なぜですか?)、UI の更新はマップのパンが完了するまでイベント キューで待機します。

于 2010-06-28T12:46:49.487 に答える