0

アプリでいくつかのクラッシュが発生しています。ログを確認してatosを使用すると、クラッシュが発生した場所が正確にわかります。これは、NSRunLoopを実行するように指示する場所です。

/**
 * Create a new thread for the timer
 *
 * @version $Revision: 0.1
 */
- (void)createTimerThread {
    NSThread *timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil];
    [timerThread start];
    [timerThread release];
}//end


/**
 * Start the actual timer
 *
 * @version $Revision: 0.1
 */
- (void)startTimerThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    // Start timer
    self.countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];

    [runLoop run];// <--- Crash happened here
    [pool release];

}//end


/**
 * Update the counter
 *
 * @version $Revision: 0.1
 */
- (void)updateCounter:(NSTimer *)theTimer {

    // Does tons of timer stuff here

}//end

ご覧のとおり、クラッシュが発生して[runLoop run]いますが、その理由はわかりません。これは通常、createTimerThread メソッドを 2 回目に呼び出したときに発生します。

ここで何が間違っていますか?私がやりたかったのは、バックグラウンドでタイマーを実行して、UILabel.

Grand Central Dispatch (GCD) のような新しいものを使用する必要がありますか?

4

2 に答える 2

1

あなたは updateCounter が UILabel を更新していて、それがバックグラウンド スレッドで実行されているタイマーから呼び出されていると言いました。それはできません。メイン スレッドで UI ビューを更新する必要があります。

performSelectorOnMainThread または GCD (メイン キューへのディスパッチ) のいずれかを使用できます。この SO 投稿のサンプルを使用して両方を比較しました。

GCD、スレッド、プログラム フロー、および UI の更新

この SO 記事には、具体的には GCD を使用した bg タイマーの例があります。

iOS4 バックグラウンド タイマーの作成

mrwalkerからの投稿を見てください

于 2011-10-17T01:40:46.107 に答える
0

UI を含むすべての呼び出しはスレッド セーフではありません。つまり、メイン スレッドで更新を行う必要があります。

あなたが実際に何を達成しようとしているのか分かりません。タイマーの「ティック」ごとに計算コストの高いことをしている場合は、ブロックを利用するのが最善の方法です。

おそらく、各ティックで何をしているか、UILabel に何を表示しているかについての洞察を私たちに与えることができますか?

于 2011-10-17T01:56:17.030 に答える