13

キープアライブを 1.5 秒ごとに別のプロセスに送信する必要があるバックグラウンド アプリケーションがあります。OSX 10.7 および 10.8 ではすべてがスムーズに機能しますが、OSX 10.9 では多くのキープアライブ通知が失われ、場合によっては 3 つまで失われます。通常、最初の 3 ~ 4 分間はすべて正常に機能し、その後問題が発生し始めます。

さらに調査した結果、OSX Mavericks の「Timer Coalescing」機能が、要求された 1.5 秒を最大 4.0 秒に延長する決定を下す責任があるようです。

合体しないように NSThread で示す方法はありますか? または、少なくとも、許容される合体のバリエーションの最大値を示すには?

参考までに、以下のコードを参照してください。

+(void)keepAliveThread
{
    @autoreleasepool {
        void (^keepAlive)() = ^ (){
            // (snipped!) do something...
        };
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        while( [NSThread currentThread].isCancelled == NO )
        {
            @autoreleasepool {
                dispatch_async(mainQueue, keepAlive);
                [NSThread sleepForTimeInterval:1.5];
            }
        }
    }
}
4

2 に答える 2

8

Apple Developer フォーラムのユーザーは、WWDC 2013 の「Improving Power Efficiency with App Nap」というタイトルのビデオを見ることを実際に勧めました。私は解決策を見つけました:

static dispatch_source_t _keepAliveTimer;

+(void)enable
{
    _keepAliveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, dispatch_get_main_queue());
    dispatch_source_set_event_handler(_keepAliveTimer, ^{
        // do something
    });
    dispatch_source_set_timer(_keepAliveTimer, dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC), 1.5 * NSEC_PER_SEC, 0.5 * NSEC_PER_SEC);
    dispatch_resume(_keepAliveTimer);
}

このコードは、LSUIElement の状態に関係なく 1.5 秒 (0.5 秒かかるかどうか) でタイマーを起動し、App Nap がそのタイマーの間だけ起動するのを防ぎます。

于 2013-10-25T11:30:36.707 に答える