как правильно проверять существование обьекта ?

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

как правильно проверять существование обьекта ?

Сообщение Attid » 17.05.2009 18:29:54

как правильно проверять существование обьекта ?

знаю два способа

generic_icons: TStringList;

if Assigned(generic_icons) then

and

if generic_icons <> nil then

оба не правильные и не работают =)
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2586
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: как правильно проверять существование обьекта ?

Сообщение Logo » 17.05.2009 19:12:33

В fpc 2.2.4 под linux вроде правильно работает, проблема была в 2.2.0 или 2.2.2

А это всегда работает.
Код: Выделить всё
 
   if generic_icons is TStringList then Label1.Caption := 'Yes'
   else Label1.Caption := 'No';
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: как правильно проверять существование обьекта ?

Сообщение Mr.Smart » 17.05.2009 19:48:45

Logo писал(а):А это всегда работает.
Код: Выделить всё
 
   if generic_icons is TStringList then Label1.Caption := 'Yes'
   else Label1.Caption := 'No';

Если переменная не инициализированна то получите ошибку доступа к памяти!

to Attid при объявлении объекта инициализируюте его как nil
Код: Выделить всё
var generic_icons: TStringList = nil;

при уничтожении пользуйтесь процедурой FreeAndNil
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: как правильно проверять существование обьекта ?

Сообщение Vadim » 17.05.2009 20:16:23

Функция Assigned() тоже просто проверяет объект на NIL, так что если переменную не проинициализировать NIL'ом, то проверить, адрес в ней объекта или шелуха, невозможно.
Можно, конечно, проверять и так, как предложил Mr.Smart
Код: Выделить всё
Try
  {Любое обращение к объекту}
Except
  on EAccessViolation do
    ShowMessage('ФигВам а не объект');
End;

Но лучше инициализировать, кода меньше...
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: как правильно проверять существование обьекта ?

Сообщение Logo » 17.05.2009 20:23:43

Mr.Smart писал(а):
Logo писал(а):А это всегда работает.
Код: Выделить всё
 
   if generic_icons is TStringList then Label1.Caption := 'Yes'
   else Label1.Caption := 'No';

Если переменная не инициализированна то получите ошибку доступа к памяти!

А проверить трудно?

Я так понял, что у Attid не стандартная ситуация. Не тот уровень у него, чтобы не понять если переменная не nil, то ее не стоит проверять на nil.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: как правильно проверять существование обьекта ?

Сообщение Mr.Smart » 17.05.2009 23:03:05

Logo писал(а):Я так понял, что у Attid не стандартная ситуация. Не тот уровень у него, чтобы не понять если переменная не nil, то ее не стоит проверять на nil.

Вопрос был имено о проверки на существование объекта, а не на проверку принадлежнасти к классу.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: как правильно проверять существование обьекта ?

Сообщение Sergei I. Gorelkin » 18.05.2009 00:09:13

В общем случае это практически невозможно. Оператор 'is', завернутый в try..except, конечно, вернет true в случае, когда возможно прочитать sizeof(Pointer) байт памяти по заданному указателю и когда эти sizeof(Pointer) байт представляют собой указатель на VMT нужного нам класса, либо на VMT его потомка. Но это ничего не говорит ни о доступности, ни о состоянии остальных полей объекта. И даже если они доступны, это может оказаться только что уничтоженный объект, который будет переписан через пару миллисекунд...

Проще следить за тем, что записывается в переменную.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: как правильно проверять существование обьекта ?

Сообщение Logo » 18.05.2009 00:59:22

Sergei I. Gorelkin писал(а):...И даже если они доступны, это может оказаться только что уничтоженный объект, который будет переписан через пару миллисекунд...

Проще следить за тем, что записывается в переменную.

Согласен на все 100%. Сам так и делаю.
Мне уже трудно найти код, написанный год назад, но при желании можно. Так вот там возникла ситуация, где гарантии нет, что неинициализированная переменная будет nil, - проверка на принадлежность к классу и выручила. Ситуация, что класс был удален, да может быть, но алгоритм программы это не предусматривал и я уверен, что этого не произойдет. Не по теории? - Конечно, но работает, а все мы по теории делаем? Что, никто классы не крякает для доступа к приватным полям? (хотя сам сейчас эту практику прекратил)

Зная по форуму Attid`а, мне и в голову не пришло, что он не смог разобраться с инициализацией переменных, я крупно сомневаюсь, что он не знал о том, что поля в классах инициализируются(обнуляются), а внешние переменные нет. Предположив, что ситуация нестандартная, я и предложил "нестандартный" метод проверки. Принимать его или нет - дело его.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: как правильно проверять существование обьекта ?

Сообщение alexs » 18.05.2009 07:28:42

В этой ситуации самое правильное решение - FreeAndNil использовать ВСЕГДА!
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4060
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: как правильно проверять существование обьекта ?

Сообщение Attid » 18.05.2009 18:37:30

ой понаписали =)

1, польщен =) но гуру тоже могут ошибаться особенно в конце дня особенно в выходной =))

2, FreeAndNil это хорошо когда ты его должен освободить, но не помогает если его не создали. но передают как созданный.


Sergei I. Gorelkin писал(а):В общем случае это практически невозможно.

чего и требовалось доказать. спасибо.
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2586
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Re: как правильно проверять существование обьекта ?

Сообщение Иван Шихалев » 18.05.2009 23:06:02

Attid писал(а):если его не создали. но передают как созданный

А в этом случае линейкой по рукам хорошо — помогает.
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Re: как правильно проверять существование обьекта ?

Сообщение Max Rusov » 19.05.2009 10:48:13

Тогда другая (уже практически осмысленная) задача. Есть объект, из него вызывается какая-то процедура. В результате сложной, непредсказуемой последовательности событий при выходе из этой процедуры может оказаться так что наш объект уже был уничтожен, соотв. обращаться к его полям и свойствам нельзя. Хочется отследить эту ситуацию и как-то обработать, например кинуть Abort. Как это сделать наиболее эффективно?
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: как правильно проверять существование обьекта ?

Сообщение Sergei I. Gorelkin » 19.05.2009 11:51:13

Так, вообще-то, оказваться не должно. И механизмы для того, чтобы этого не происходило, есть разные:
1) Интерфейсы+подсчет ссылок (объект не удаляется до тех пор, пока его кто-то использует)
2) Уведомление об уничтожении (TComponent.FreeNotification и сотоварищи)
3) Отложенное удаление (объект ставится в очередь и уничтожается несколько позже, когда уже можно. См. TForm.Release).
4) Не удалять вообще, в конце концов.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: как правильно проверять существование обьекта ?

Сообщение Max Rusov » 19.05.2009 12:23:28

2 - для данной задачи не поможет
4 - это не решение проблемы, это отказ от решения.
1 и 3, да это путь. Но зачастую слишком сложный, может потребоваться перепроектировать пол системы.

Пример задачи: есть некий интерфейс-билдер с кнопочками и событиями OnClick. Что напишут в обработчике OnClick -
заранее неизвестно, могут убить и кнопочку, и форму на которой она лежит. В "обычном" языке - это приведет к AV - сам дурак.
А вот в "защищенной" среде - хотелось бы выдать цивильную ошибку...
Max Rusov
постоялец
 
Сообщения: 191
Зарегистрирован: 25.04.2009 15:46:03

Re: как правильно проверять существование обьекта ?

Сообщение Logo » 19.05.2009 12:36:16

Max Rusov писал(а):Тогда другая (уже практически осмысленная) задача. Есть объект, из него вызывается какая-то процедура. В результате сложной, непредсказуемой последовательности событий при выходе из этой процедуры может оказаться так что наш объект уже был уничтожен, соотв. обращаться к его полям и свойствам нельзя. Хочется отследить эту ситуацию и как-то обработать, например кинуть Abort. Как это сделать наиболее эффективно?

Я у себя выкрутился из подобной ситуации таймером. После подачи команды на удаление, сначала блокируется доступ к объекту и запускается таймер на гарантированное время, чтобы все внутренние операции закончились. После истечения заданного времени, объект уничтожается. Можно и счетчик обращений с блокировкой применить, но с таймером оказалось проще.

Добавлено спустя 11 минут 26 секунд:
Max Rusov писал(а):Пример задачи: есть некий интерфейс-билдер с кнопочками и событиями OnClick. Что напишут в обработчике OnClick -
заранее неизвестно, могут убить и кнопочку, и форму на которой она лежит. В "обычном" языке - это приведет к AV - сам дурак.
А вот в "защищенной" среде - хотелось бы выдать цивильную ошибку...


Наверное переписывать Destroy и вводить проверку, если вызов сделан от потомка, то блокировать. Хотя, как это реализовать, на данный момент не представляю.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru