Интересно, что ни один из ответов на этой странице не упоминает два крайних случая, надеюсь, никто не возражает, если я их добавлю:
Родовые словари в .NET не являются потокобезопасными, а иногда могут бросать NullReference
или даже (чаще) a KeyNotFoundException
при попытке получить доступ к ключу из двух параллельных потоков. Исключение в этом случае является довольно ошибочным.
Если код NullReferenceException
задан кодом unsafe
, вы можете посмотреть на переменные указателя , и проверьте их на IntPtr.Zero
или что-то в этом роде. Это одно и то же («исключение нулевого указателя»), но в небезопасном коде переменные часто переводятся в типы значений / массивы и т. Д., И вы ударяете головой о стену, задаваясь вопросом, как тип значения может исключение.
(Еще одна причина для небезопасного использования небезопасного кода, если вам это нужно)
Кажется, что это сработает:
При следующем запуске приложения загрузите предыдущее значение для 'lr', вычислите новый , и если они будут отличаться, вы обнаружите перезагрузку (вам, вероятно, придется терпеть небольшую разницу ... возможно, пару миллисекунд).
Я думаю, было бы довольно сложно обмануть это. .. пользователь должен был бы точно изменить время своего телефона, и они должны были бы начать ваше приложение в очень точный момент поверх этого, точно, когда новый «lr» был бы идентичен предыдущему ... pretty трудно сделать, вероятность того, что они могут это сделать, очень близка к 0 I th чернила. И вам не нужно какое-либо интернет-соединение, чтобы это сделать ...
Новый «lr» был бы идентичен предыдущему в следующих случаях:
Вот один, который я сделал. Он занимает текущее время в GMT и время после последней перезагрузки, чтобы экстраполировать дату, когда устройство было в последний раз перезапущено. Затем он отслеживает эту дату в памяти с помощью NSUserDefaults. Наслаждайтесь!
Примечание. Поскольку вы хотите проверить это с момента запуска приложения в последний раз, вам нужно убедиться, что вы вызываете метод в любое время, когда приложение запущено. Самый простой способ - вызвать метод ниже в +(void)initialize {
, а затем, когда вам нужно его вручную проверить
#define nowInSeconds CFAbsoluteTimeGetCurrent()//since Jan 1 2001 00:00:00 GMT
#define secondsSinceDeviceRestart ((int)round([[NSProcessInfo processInfo] systemUptime]))
#define storage [NSUserDefaults standardUserDefaults]
#define DISTANCE(__valueOne, __valueTwo) ((((__valueOne)-(__valueTwo))>=0)?((__valueOne)-(__valueTwo)):((__valueTwo)-(__valueOne)))
+(BOOL)didDeviceReset {
static BOOL didDeviceReset;
static dispatch_once_t onceToken;
int currentRestartDate = nowInSeconds-secondsSinceDeviceRestart;
int previousRestartDate = (int)[((NSNumber *)[storage objectForKey:@"previousRestartDate"]) integerValue];
int dateVarianceThreshold = 10;
dispatch_once(&onceToken, ^{
if (!previousRestartDate || DISTANCE(currentRestartDate, previousRestartDate) > dateVarianceThreshold) {
didDeviceReset = YES;
} else {
didDeviceReset = NO;
}
});
[storage setObject:@(currentRestartDate) forKey:@"previousRestartDate"];
[storage synchronize];
return didDeviceReset;
}
Получите и сохраните время либо с iPhone, либо с NIST и текущего времени исполнения из функции повышения производительности BSD. Для времени NIST см. Как я могу получить реальное время в iPhone, а не время, заданное пользователем в настройках?
Когда вы хотите проверить перезагрузку, получите новые значения этих , вычислить прошедшее время для каждого и сравнить прошедшее время. Исходя из разницы, вы должны иметь возможность определить перезагрузку.
// Returns true if device has rebooted since last time
private func deviceRebootedSinceLastTime() -> Bool {
let userDefaults = NSUserDefaults.standardUserDefaults()
let systemUptime = NSProcessInfo.processInfo().systemUptime;
let timeNow = NSDate().timeIntervalSince1970
let dateOfLastReboot = NSDate(timeIntervalSince1970: timeNow-systemUptime)
var didDeviceRebootSinceLastTime = false
if let storedDateOfLastReboot:NSDate = userDefaults.objectForKey("deviceLastRebootDate") as? NSDate {
if Int(dateOfLastReboot.timeIntervalSinceDate(storedDateOfLastReboot)) < 1 { //
print("Reboot time didn't change - date: \(dateOfLastReboot)");
}
else {
print("Reboot time has changed - from: \(storedDateOfLastReboot) to \(dateOfLastReboot)");
didDeviceRebootSinceLastTime = true
}
}
else {
print("Reboot time is saved for the first time")
didDeviceRebootSinceLastTime = true // first time we save value
}
userDefaults.setObject(dateOfLastReboot, forKey: "deviceLastRebootDate")
userDefaults.synchronize() // don't forget this!!!
return didDeviceRebootSinceLastTime;
}
Ответ Зорана - правильный путь; это самое близкое, что вы получите без сетевого подключения. (ни мобильная подсистема, ни системный журнал не доступны по соображениям безопасности).
Если вы хотите предотвратить появление вредоносных данных от вредоносных пользователей, обратитесь к треку центрального сервера (или доверенного локального сервера для развертывания предприятия) связанные с временем события.