web-dev-qa-db-ja.com

iPhoneベースのmach_absolute_timeとは

私はこのコードを使用して、最後の再起動を追跡します。

+ (float) secondsSinceLastReboot{
     return ((float)(mach_absolute_time())) * ((float)timebase.numer) / ((float)timebase.denom) / 1000000000.0f;
}

私はmach_absolute_time()がMacのように最後のデバイスの起動時間に基づいていると想定しました。それはそれに基づいていないようです。それが何に基づいているのか、実際にはわかりません。

次の動作を見てください(今日の日付は2009-09-20です)。

lastRebootTime = [[NSDate date] addTimeInterval:-[self secondsSinceLastReboot]];
//last Reboot Time will contain : 2009-09-20 07:42:14 +0100

その時点でデバイスを再起動しなかったのは間違いありません。デバイスが1週間以内に起動しません。

さらに、デバイスをケーブルから外してこのアプリを実行すると、デバイスがスリープ状態になると、lastRebootTimeが将来シフトし始めるようです。 mach_absolute_timeがスリープ時間を考慮していないようです。それとも私はこれについて間違っていますか?

デバイスが最後に再起動したときからタイムスタンプを取得できるようにしたいのですが。何か案は?

31
Maxm007

私自身、これに問題がありました。良いドキュメントがたくさんないので、実験をしました。これが私が決定できたものです:

mach_absolute_timeは、デバイスのプロセッサに依存します。デバイスが最後に再起動されてからのティックを返します(そうでない場合は稼働時間として知られています)。人間が読める形式で取得するには、mach_timebase_infoの結果(比率)で変更する必要があります。これにより、10億分の1秒(またはナノ秒)が返されます。これをより使いやすくするために、以下のような関数を使用します。

#include <mach/mach_time.h>

int getUptimeInMilliseconds()
{
    const int64_t kOneMillion = 1000 * 1000;
    static mach_timebase_info_data_t s_timebase_info;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        (void) mach_timebase_info(&s_timebase_info);
    });

    // mach_absolute_time() returns billionth of seconds,
    // so divide by one million to get milliseconds
    return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
49
BadPirate

計算時間をあまり気にしない場合は、Foundationの単純なObj-Cクラスを使用できます

NSTimeInterval systemUptime = [[NSProcessInfo processInfo] systemUptime];
9
malex

Swift(4.2および5.0で動作))で誰かがそれを必要とする場合。

let beginTime = mach_absolute_time()

// do something...

var baseInfo = mach_timebase_info_data_t(numer: 0, denom: 0)
if mach_timebase_info(&baseInfo) == KERN_SUCCESS {
    let finiTime = mach_absolute_time()

    let nano = (finiTime - beginTime) * UInt64(baseInfo.numer) / UInt64(baseInfo.denom)
}
1
Mint