![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как убить объект из его же метода? [D7]
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