2

Interface Builder で設計された GUI を使用して、Cocoa アプリケーションを作成しています。UI をブロックせずに (定期的に) バックグラウンド アクティビティをスケジュールする必要があるため、次のように別のスレッドで実行します。

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    [self performSelectorInBackground:@selector(schedule) withObject:nil];
}

- (void) schedule {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];

    timer = [[NSTimer scheduledTimerWithTimeInterval:FEED_UPDATE_INTERVAL
                                                  target:activityObj
                                        selector:@selector(run:)
                                        userInfo:nil
                                         repeats:YES]
         retain];

    [runLoop run];
    [pool release];
}

タイマーを保持しているので、簡単に無効にして再スケジュールできます。

問題: GUI イベントに応答して run: メソッドも起動する必要があるため、これは同期的です (つまり、「アクティビティを実行する」ボタン)。このような:

[timer fire];

performSelectorInBackground でもこれを行うことができ、もちろん UI をブロックしません。しかし、この同期発火は別の実行ループで実行されます! したがって、それらが重複しないという保証はありません。同じ実行ループですべての発火をキューに入れるにはどうすればよいですか?

4

3 に答える 3

0
[timer setFireDate:[NSDate distantPast]];

過去の日付を setFireDate に渡すことで、次の起動日を ASAP に調整することで、目的の効果が得られました。

于 2010-06-18T10:59:11.693 に答える
0

NSTimer が追加されるため、GCD を介してバックグラウンド スレッドで NSTimer をスケジュールするのではなく、mainThread で NSTimer をスケジュールする (そしてセレクターを実行するためにタイマーを起動する --- セレクターはバックグラウンド スレッドで実行できるため、UI をブロックしない) 必要があります。 NSRunLoop に接続し、すべての NSRunLoop は NSTread に関連付けられています。したがって、GCD を使用する場合は、NSTimer の代わりに dispatch_after を使用して、発生することを遅らせます。

于 2016-02-27T09:49:02.093 に答える