Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];

Вниз

Можно ли уничтожить объект в его же обработчике ? И как ?   Найти похожие ветки 

 
Begin   (2002-11-23 01:21) [0]

В хелпах написано, что нечто.Free низя использовать в обработчиках этого нечто. А надо. А как ?

P.S. Где то тут я видел такой вопрос, но в ФАКе не нашел, а все архивы смотреть терпения нет. Если сложно не будет, ответьте плиз еще раз.... :)


 
Fantasist   (2002-11-23 08:48) [1]

Можно послать сообщение, если он умеет их принимать.


 
Anatoly Podgoretsky   (2002-11-23 11:45) [2]

Можно, но не нада, плохо будет.
Думай над алгоритмом, там что то не ладно


 
ЮЮ   (2002-11-23 12:05) [3]

Его же кто-то создал? Вот и напиши последним оператором в методе
Owner(Parent).Delete(self) а уж Owner(Parent) пусть реально решает судбьу самоубийцы.


 
Cobalt   (2002-11-23 13:24) [4]

Можно поробовать следующее:
Добавить свойство типа KillMe:boolean;
А вызывающий объект (процедура et cetera) будет смотреть в ключевые моменты - надо убить или нет.


 
Юрий Зотов   (2002-11-23 13:33) [5]

Однако же, форма сама себя уничтожать умеет (см. Release и CMRelease в TCustomForm). Именно посылкой сообщения

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


 
AlexandrN   (2002-11-23 13:38) [6]

Поставиь на форму компонент TButton.
В обработчике OnClick напиши.
Sender->Free();

Откомпили и запусть.
Button Исчез, память освободилась, можно спокойно далише работать и ни очём не думать...



 
les   (2002-11-23 14:17) [7]

Ужас


 
AlexandrN   (2002-11-23 14:19) [8]

Причём сдесь ужас, нормально работает.


 
Ihor Osov'yak   (2002-11-23 14:20) [9]

2 AlexandrN (23.11.02 13:38)

Имхо, пример некорректен, ибо запуск процесса уничтожения идет извне (из метода формы, а не бутона).

По большому счету - путь только один, как уже говорилось - посылкой сообщений (Fantasist © (23.11.02 08:48),Юрий Зотов © (23.11.02 13:33)), но через PostMessage, и возможно предварительно выставив некий флажок для быстрого отката по стеку процедур (см Юрий Зотов еще раз) сразу после PostMessage или юзать для той же цели Abort (здесь откат до первого обработчика исключений).. Флажок также позволяет организовать выход в начале каждого обработчика сооощений (ибо в очереде сообщений перед той коммандой на уничтожение, что была послана через PostMessage, могут быть еще необработанные комманды, которые уже не нужно (и даже опасно обрабатывать, если по ходу своих обработчиков Вы увлекаетесь Application.ProcessMessages)

Хотя если возникает необходимость в быстром откате - то это есть в большинстве случаев сигнал о несколько нерашливом стиле кодирования (имхо), также см Anatoly Podgoretsky © (23.11.02 11:45), хотя бы я не был бы столь категоричным...


 
Song   (2002-11-23 14:21) [10]

AlexandrN (23.11.02 13:38), ты откуда такой умный взялся? :-)


 
Юрий Зотов   (2002-11-23 14:26) [11]

> AlexandrN (23.11.02 13:38)

Это не совсем тот пример. Кнопка уничтожается кодом ФОРМЫ, а не самой кнопки, хотя вызывается он действительно из кода кнопки (метод Click). При возврате из стека вызовов не происходит обращений к полям кнопки, поэтому все проходит нормально. Но если такие обращения будут - получим ошибку. Скажем, если уничтожить модально показанную форму, то она исчезнет, но программа завершится с ошибкой - именно из-за того, что в методе ShowModal есть обращения к полям формы.

Вывод - самоуничтожающийся объект делать можно, но аккуратно.


 
Fantasist   (2002-11-24 09:22) [12]


> Вывод - самоуничтожающийся объект делать можно, но аккуратно

Да самоуничтожающийся объект чаще всего вещь довольно безопасная. Не опаснее, чем удаление его из другого места - и так и так при неаккуратности можно попытатся использовать освобожденную память. А речь идет как раз об удалении из обработчика - и это как раз не самоуничтожающийся объект, так как обработчик это метод не того объекта, который хочеться удалить.

Чтобы было понятнее, на примере (это не для Юрия Зотова, которому это и так понятно, а для других, кому пока не очень понятно):


TNotifyEvent=procedure (Sender:TObject) of object;

TWorkClass=class
private
fCompleted:boolean;
public
procedure DoWork;
OnWorkComplete:TNotifyEvent;
end;

TKillerClass=class
public:
constructor Create;
procedure WorkDone(Sender:TObject);
end;

.....

constructor TKillerClass.Create;
var
wkc:TWorkClass;
begin
wkc:=TWorkClass.Create;
wkc.OnWorkComplete:=WorkDone;
wkc.DoWork;
end;

TKillerClass.WorkDone(Sender:TObject);
begin
Sender.Free;
end;

TWorkClass.DoWork;
begin
fCompleted:=false;
DoWork;
if Assigned(OnWorkComplete) then
OnWorkComplete(Self); //Здесь выполниться TKillerClass.WorkDone освоботит память из под этого объекта
fCompleted:=true; //Память уже освобождена из под этого класса, а мы пытаемся к ней обратиться.
end;


Вот если бы строчки: fCompleted:=true; не было то все бы прошло гладко. Но рассчитывать на это никогда не стоит.


 
Fantasist   (2002-11-24 09:27) [13]

Гхм... Не стоило пример приводить на ночь глядя. Написал бесконечную рекурсию и без keywords.
Ну в общем, тот кто надо тот понял. :) Замените в TWorkClass.DoWork строчку с DoWork на что-нибудь типа DoOuterWork, и будет нормально.


 
Milch   (2002-11-24 12:35) [14]

....
procedure CMRelease(var Message: TMessage); message CM_RELEASE;
....
....
procedure TForm1.CMRelease;
begin
free;
end;

procedure TForm1.Release;
begin
PostMessage(Handle, CM_RELEASE, 0, 0);
end;


 
Begin   (2002-11-25 04:00) [15]

Большое всем спасибо за массу ответов... :) Но все же...

В моем конкретном случае хочется сделать возможность самоуничтожения в обработчите OnClick, который вызывается TImage"м... Хендла у его нет, так что самоубить его, используя сообщения, не выходит. Если пытаться использовать Free, компилятор утыкается в end и жалуется на аксес виолейшн. Пытался вызывать другую процедуру, которая бы его убила, но получается та же итория, как с free. Как быть ???



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.12.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.009 c
3-14374
Senka
2002-11-19 14:46
2002.12.05
Проблема с русскими шрифтами в Database Desktop в Win2k


3-14461
Брат
2002-11-18 16:20
2002.12.05
Количество записей в таблице...


3-14391
eLVik
2002-11-14 18:24
2002.12.05
Помогите новичку!!!


7-14829
DaTak
2002-10-02 14:28
2002.12.05
Bios и Delphi


3-14402
Mic_2000
2002-11-15 10:47
2002.12.05
Помогите разобраться с DBComboBox и DBListBox





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский