Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как убить объект из его же метода? [D7]


Страницы:   1 2 3 4 5 6

Ega23 ©   (2007-10-12 13:17:00) 

Собственно, сабж.

Есть идея с PostMesage  WM_DESTROY, но возникает вопрос - а если это не "оеонный" класс?


Ins   (2007-10-12 15:37:00) [61]


> oxffff ©   (12.10.07 15:32) [42]

Практика показывает, что на эти грабли периодически наступают. Именно из-за непонимания того, что после вызова Free метод представляет собой некий чемоданчик с проводками, из которого раздается тик-так. Не верите мне - верьте статистике :)


Игорь Шевченко   (2007-10-12 15:35:00) [62]

на С# надо писать. Там мусор собирается. Сам.


oxffff   (2007-10-12 15:32:00) [63]


> Ins ©   (12.10.07 15:20) [39]
>
> > palva ©   (12.10.07 15:12) [37]
>
> Просто можно сделать безопасно. Сделав это не из метода
> своего класса. Иначе - небезопасно, так как метод продолжает
> выполняться с невалидным self. Повезет-неповезет, зависит
> от того, как это реализует программист. Задумается ли он
> о многих не очень очевидных вещах (в частности, что не только
> к полям нельзя обращаться, но и к виртуальным методам).
> И от того, откуда этот метод вызван. Если из другого метода,
>  то теперь ответственность на том другом методе.


Если слегка подумать и подмутить, то можно сделать так, что после вызова Free можно у объекта вызывать методы, в том числе и виртуальные и обращаться к полям. :)
Все в твоих руках. Это так к сведению


Ins   (2007-10-12 15:31:00) [64]

Даже PostMessage самому себе (как сделано в Release) тоже не так чист как кажется с той точки зрения, что обработчик сообщения вызывается из другого метода (Dispatch что-ли), а тот - из WndProc. Если ничего не путаю, точнее нужно глянуть исходники. Так вот, вызывая Free в обработчике CM_Release - мы полностью доверяем Борланду, что после вызова этого обработчика и возврата в Dispatch и WndProc не будет никакого обращения к Self. Так что делая так, скрестите пальцы и молитесь-молитесь... :) Хотя на самом деле не будет, Борланд об этом позаботился.


oxffff   (2007-10-12 15:26:00) [65]

Можно убивать по разному, главное чтобы убить. А как это без разницы.


Ins   (2007-10-12 15:20:00) [66]


> palva ©   (12.10.07 15:12) [37]

Просто можно сделать безопасно. Сделав это не из метода своего класса. Иначе - небезопасно, так как метод продолжает выполняться с невалидным self. Повезет-неповезет, зависит от того, как это реализует программист. Задумается ли он о многих не очень очевидных вещах (в частности, что не только к полям нельзя обращаться, но и к виртуальным методам). И от того, откуда этот метод вызван. Если из другого метода, то теперь ответственность на том другом методе.


Leonid Troyanovsky   (2007-10-12 15:13:00) [67]


> Игорь Шевченко ©   (12.10.07 14:58) [31]

> И получится ошибка, вас это не удивит ? :)

А я и не делал ничего подобного Foo.Bar := smth.

Более того, в хелпе обещали, что Release сработает
после выхода из обработчика (какая самонадеянность)

--
Regards, LVT.


palva   (2007-10-12 15:12:00) [68]

> Можно, даже варианты предложены.
Ну это уже не из метода будет. Автор хочет из метода. И у него нет никаких препятствий (кроме заповеди "не убий") это сделать. Небезопасно - это возможно. Но настолько же небезопасно, как в основной программе уничтожить объект и сразу же им воспользоваться.


Игорь Шевченко   (2007-10-12 15:10:00) [69]

Ins ©   (12.10.07 15:06) [34]

Я к тому, что твой и Леонида примеры по сути аналогичны моему с заведомым удалением объекта.
Но никто же при этом не утверждает, что вызов Free небезопасен, нес па ?


palva   (2007-10-12 15:07:00) [70]

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


Ins   (2007-10-12 15:06:00) [71]


> Как убить, если убивать нельзя.

Можно, даже варианты предложены. :) В большинсвте своем они подобны методу Release - посылка асинхронногосообщения. Только разница в том кому посылать. Если самому себе (правда нужно чтобы объект был оконным), то нужно соблюсти правило "необращения к Self после Free".


Ins   (2007-10-12 15:03:00) [72]


> И получится ошибка, вас это не удивит ? :)

Не удивит. Меня удивляет лишь то, что вы тоже самое и предлагаете сделать, и говорите, что это вполне себе безопасно. :) Хотя, хозяин-барин, просто когда вы, или тот, кому вы посоветуете так сделать, не обговорив все "но", разобьет себе лоб - не удивляйтесь.


palva   (2007-10-12 14:59:00) [73]

Вобщем я так и не понял вопроса. Как убить, если убивать нельзя.


Игорь Шевченко   (2007-10-12 14:58:00) [74]

Ins ©   (12.10.07 14:40) [28]
Leonid Troyanovsky ©   (12.10.07 14:49) [30]

Если в коде написать:

Foo.Free
Foo.Bar := smth

И получится ошибка, вас это не удивит ? :)


Leonid Troyanovsky   (2007-10-12 14:49:00) [75]


> Игорь Шевченко ©   (12.10.07 14:29) [25]

> Вроде безопасно...

Особенно забавно в главной форме:

procedure TForm1.Button1Click(Sender: TObject);
begin
 Release;
 ShowMessage('The end');
end;

т.е., приложение продолжит жить бесформенно.

--
Regards, LVT.


Ins   (2007-10-12 14:46:00) [76]


> Вроде безопасно...

Только при соблюдении ряда условий, которые Borland сами для нас соблюли (см метод Release).


Ins   (2007-10-12 14:40:00) [77]


> Вроде безопасно...CMRelease - это факт, СВОЙ метод для объекта
> TCustomForm

Безопасно? Ну пошлите это сообщение (CM_RELEASE) через SendMessage или Perform где-то из глубины кода метода, который потом еще что-то делает с self-ом. Посмотрим :) Вот даже пример:

procedure TForm1.Button1Click(Sender: TObject);
begin
 Perform(CM_RELEASE,0,0);
 Caption:='123';
end;


Я не говорю, что так делать нельзя. Я говорю, что это небезопасно и рано или поздно свой эксепшн поймаешь.


Ins   (2007-10-12 14:31:00) [78]


> В потоке например, который будет этот список без конца сканить
> и мочить объекты…

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


Игорь Шевченко   (2007-10-12 14:30:00) [79]


> Это очень важное если. А если этот метод вызван из другого
> метода, который потом обращается? А если этот другойвызван
> из третьего? А если где-то потом еще вызывается виртуальный
> метод (он же тоже подразумевает обращение к self)? Лучше
> просто так не делать и тогда жить будет чуточку легче.


Совсем легко станет если учить матчасть. (Уж извини)


Игорь Шевченко   (2007-10-12 14:29:00) [80]

Ins ©   (12.10.07 14:00) [18]


> В своем же методе (сабж вроде как об этом) вызывать Free
> небезопасно. После этого вызова метод продолжает выполняться,
>  но экземпляра, на который указывает self уже нет.


???????????????????????????????????????????????????????????

procedure TCustomForm.CMRelease;
begin
 Free;
end;

Вроде безопасно...CMRelease - это факт, СВОЙ метод для объекта TCustomForm


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо