Поскольку этот вопрос по-прежнему привлекает много пользователей из поиска Google (о таймере Android), я хотел бы вставить две мои монеты.
Прежде всего, Timer класс будет устаревшим в Java 9 (прочитайте принятый ответ) .
Предполагаемый способ official - использовать ScheduledThreadPoolExecutor , который является более эффективным и богатым функциональными возможностями, который может дополнительно планировать команды для запуска после определенной задержки или для выполнения периодически. Кроме того, это дает дополнительную гибкость и возможности ThreadPoolExecutor.
Вот пример использования простых функций.
final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
final Future> future = SCHEDULER.schedule(Runnable task, long delay,TimeUnit unit);
future
для отмены задачи или проверить, выполнено ли это, например: future.isDone();
Надеюсь, вы найдете это полезным для создания задач в Android.
Полный пример:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Future> sampleFutureTimer = scheduler.schedule(new Runnable(), 120, TimeUnit.SECONDS);
if (sampleFutureTimer.isDone()){
// Do something which will save world.
}
Нет, вы не можете. Зачем? Потому что было бы дорого поддерживать метаданные о том, что представляет собой действительный указатель, а что нет, а на C ++ вы не платите за то, чего не хотите.
И вы не хотите проверить, является ли указатель действительным, потому что вы знаете , откуда указатель, либо потому, что он является частной частью вашего кода, который вы контролируете, либо потому, что вы указали его в ваши внешние контракты.
Если указатель установлен на nullptr
, это означает, что ему не был дан объект, на который он указывает, и вместо этого ему было присвоено значение «по умолчанию». Возможно, указатель мог not быть назначен nullptr
и в то же время не назначен действительному объекту, но в этом случае определить его невозможно. Например:
С nullptr
:
int *ptr = nullptr;
// check if pointer is unassigned to an object
if (ptr == nullptr) ptr = new int{0};
Без nullptr
:
int *ptr;
// using ptr while uninitialized is Undefined Behavior!
if (ptr != &some_object)
Как указано в других ответах, это невозможно с необработанным указателем формы SomeObject* somePointer
. Однако c++11
представил новый набор управления динамической памятью и новых интеллектуальных указателей . Используя интеллектуальный указатель, вы можете определить, доступен ли ресурс. Например, в следующем:
std::weak_ptr<int> w; // Our pointer to a resource.
{
std::shared_pointer<int> s = std::make_shared<int>(5); // The resource.
w = s; // We can set the weak pointer to the shared pointer.
auto s2 = w; // Here we can promote the weak pointer to a shared pointer to control
// the resource.
*s2 = 6; // Here we can use the resource.
} // Here the resource is destroyed.
auto s2 = w; // Here we will fail to get the resource because it has been destroyed. We
// have successfully used smart pointers to detect if the resource exists.
Подробнее о std :: shared_ptr и std :: weak_ptr для получения дополнительных примеров. До c++11
эквивалентные типы интеллектуальных указателей доступны в boost
.
auto_ptr
здесь, потому что мне понадобится страница, почему бы не использовать его. Я добавлю также примечание об усилении.
– Fantastic Mr Fox
7 February 2018 в 01:48
Невозможно. Подумайте об этом сценарии.
int *ptr = new int(10);
int *ptrDup = ptr;
delete ptr;
Но ptrDup
все еще указывает на ячейку памяти, на которую указывает ptr
, которая больше не существует. Таким образом, отсрочка ptrDup
приводит к неопределенному поведению. Но есть подсчет ссылок, который является совершенно другой концепцией.
Невозможно увидеть, является ли указатель «действительным» во всех его значениях.
Конечно, вы можете попытаться разыменовать указатель (*ptr = x;
или x = *ptr
). Если ваш код не сбой, указатель указывает на действительную память. Если он упал, очевидно, указатель не годится. К сожалению, этот подход немного похож на проверку того, загружена ли пушка, выстрелив в голову - что не самое умное ... К сожалению, с указателями нет «проверьте камеру, чтобы увидеть, загружена ли она», поэтому нет реального хорошего способа выяснить, является ли указатель действительным, кроме «если он не вызывает аппаратную ошибку, он действителен».
Обратите внимание, что это только на самом деле скажет вам, что «указатель указывает на некоторую память, к которой вы можете получить доступ» в большинстве случаев. Это НЕ означает, что указатель «правильный для того, что вы хотите» (например, указывает на правильный тип). И это НЕКОТОРНО не скажет вам, указывает ли указатель на «устаревшие данные» (то есть, когда указатель WAS действителен, но теперь он используется для чего-то другого).
К сожалению, с 232 или 264 [fактически 248] возможно действительными адресами памяти в современной системе, почти невозможно узнать, какие адреса действительны, а какие нет. Даже внутри операционной системы, как показывает ОС, если она может записать в память, которую вы попросили написать, это «попытаться написать ее, посмотреть, что произойдет». Для ОС это работает отлично, потому что это может быть осторожным, «это может пойти не так, и если это произойдет, я продолжу там в коде восстановления ошибок». ОС должна справиться с этим, потому что она должна принять, а) что программисты совершают ошибки, и б) что некоторые люди на самом деле пишу вредоносный код для TRY, чтобы разорвать ОС.
Способ для приложения «убедиться, что указатели действительны» - это то, что программист пишет код, который ОСТОРОЖНО, о том, что он хранит в указателях, как он освобождает эти указатели и использует только указатели с допустимыми значениями хранится в них. Вы не должны заканчивать «необходимость проверки правильности указателя» - тогда вы «делаете это неправильно».
(Когда вы некоторое время работаете с системой и читаете значения указателя в отладчике, вы через некоторое время узнаете «хорошие» и «плохие» указатели, но это только потому, что вы узнаете, что обычно , хороший указатель против плохого указателя выглядит так: писать код для распознавания такого почти невозможно - особенно если система выделяет много памяти, поэтому использует большую часть доступного пространства.)
Конечно, в C ++ существуют интеллектуальные указатели, векторы и различные другие инструменты, которые означают много времени, когда вам даже не нужно беспокоиться о указателях. Но понимание того, как использовать указатели и как работают указатели, по-прежнему хорошо.
delete
, и в этом случае он может выглядеть так: правильно и, похоже, работают, но на самом деле возвращают мусор из зомби, который просто находится в пределах допустимого диапазона памяти вашего приложения. Итак, со всеми этими gotchas, возможно, лучше просто оставить его в «Нет». после чего следует избегать проверки правильности исходного указателя?
– Agentlien
20 June 2013 в 09:49