2013-10-24 15 views
12

私は1.5秒ごとに別のプロセスにキープアライブを送信する必要があるバックグラウンドアプリケーションを持っています。 OSX 10.7と10.8ではすべてがスムーズに動作しますが、OSX 10.9では多くのキープアライブ通知が見逃されます.3回になることもあります。通常、最初の3〜4分間は正常に動作し、問題が発生します。OSXで特定のプロセスのタイマー統合を無効にする

さらに検査した後、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]; 
      } 
     } 
    } 
} 
+0

ユーザーがアプリごとにオフにできることは間違いありませんが、それはおそらくあなたが本当に必要とする解決策ではないでしょう。 – Kevin

+1

メインスレッドでキープアライブ作業を行う必要があるのはなぜですか? – trojanfoe

+1

問題は、実際にメインスレッドまたはセカンダリスレッドで発生しても問題は発生しませんでした。 App Napは、現在表示されているUIエレメントが表示されていないすべてのアプリケーションに適用されます。すべてのUI要素が非表示または閉じている場合、App Napによってタイマーが遅くなることがアプリケーションに表示されます。 – ekscrypto

答えて

6

あなたが適切な.plistキーを設定せずにバックグラウンドアプリケーションを実行しているように聞こえます。

バックグラウンドアプリケーションを使用している場合は、アプリケーションのplistで 'Application is agent(UIElement)'(LSUIElement)オプションをYESに、または 'Application is background only'(LSBackgroundOnly)それ以外の場合は、App Napの対象となります.App Napは、この場合に発生しているものです。私はタイマー間隔で巨大なギャップを生み出すためにタイマーの合体を期待しません。

LSUIElementは、フローティングウィンドウまたはステータスバーのアイテムだけのアプリケーションを対象としています。メニューバーは表示されず、ドックアイコンは表示されません。

App Napは、フロントアップユーザーアプリケーションに影響するように設計されています。アプリの原因となります4つの物事がアプリ-昼寝に送信されることになっているが、ドキュメントによると、あります:それはある

  • 見えない-場合は、アプリのウィンドウのすべてがいずれかの他のウィンドウで隠されたりして、最小化されています隠しドック、およびアプリがフォアグラウンド
  • にそれはあなたがしたい場合は、任意の電源管理アサーション

を取っていない

  • 明示的に無効になっていない自動終了を持って
  • 聞こえないされていませんユーザーアプリケーションがApp napを経験しないようにするには、これらの状態の1つをアクティブにしないためにサポートされているメカニズムの1つに従わなければなりません。

    IOPmlib.h APIを使用している場合は、アプリのパワーマネージメントアサーションを作成してアプリのナップを防ぐことができます。

    Alternativaly、あなたが使用して自動終了を無効にすることができます

    [[NSProcessInfo processInfo] disableAutomaticTermination:@"Good Reason"]; 
    

    をそして再び自動終了を有効にする:

    [[NSProcessInfo processInfo] enableAutomaticTermination:@"Good Reason"]; 
    

    しかし、アプリがある前に、これは一般的に行われる必要があるコードを対象としてい「良いことを止める」と考えられた嗜好を書く。

    アップルでは、​​アプリケーションに関連する問題が発生している場合は、その実装のバグかどうかを判断できるようにレーダーを提出する必要があります。

  • +0

    私は、sleepIntervalが固定されたNSThreadがNSTimerよりも厳格で固定された動作をしていると考えていました。それでなぜ私はそのようにしたのですか? – ekscrypto

    +0

    NSTimerを使って試してみました.30分のバックグラウンドで実行した後、NSTimerの間隔は1.5秒に設定され、1.0秒の余裕があり、12秒を超えて解雇されませんでした。 – ekscrypto

    +0

    質問から、LSUIElementまたはLSBackground専用のアプリのように聞こえますが、これはApp Napの対象ではありません。 –

    8

    Appleデベロッパーフォーラムのユーザーが実際におすすめしているのは、「App Napで電力効率を改善する」と題されたWWDC 2013からのビデオです。ここで私は解決策を見つけた:

    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状態の(0.5秒を与えるか、または取る)1.5秒にタイマーを発射し、それだけでタイマーの中に蹴りからのAppナップを防ぐことができます。

    関連する問題