Самоубийство
Модератор: Модераторы
Самоубийство
Вопрос с подвохом.
Можно ли объекту из себя прибить себя или же поручив это господину, но вызвав его метод из себя же, а затем вернувшись в себя, зомби.
Кто ничего не понял, может посмотреть код тут https://github.com/Tango600/dcl5/blob/master/src/uUDL.pas.
убивается объект TDCLForm, при закрытии формы, убивает его TDCLLogOn. На выходе из метода TDCLLogOn.CloseForm получаю SIGSEV.
Как правильно убить объект.
Можно ли объекту из себя прибить себя или же поручив это господину, но вызвав его метод из себя же, а затем вернувшись в себя, зомби.
Кто ничего не понял, может посмотреть код тут https://github.com/Tango600/dcl5/blob/master/src/uUDL.pas.
убивается объект TDCLForm, при закрытии формы, убивает его TDCLLogOn. На выходе из метода TDCLLogOn.CloseForm получаю SIGSEV.
Как правильно убить объект.
- alexs
- долгожитель
- Сообщения: 4066
- Зарегистрирован: 15.05.2005 23:17:07
- Откуда: г.Ставрополь
- Контактная информация:
Код: Выделить всё
Application.ReleaseComponent(T);
Именно для этого и предназначено.
PS
Ну и тема... Ещё связисты забанят....
Можно ли объекту из себя прибить себя или же поручив это господину, но вызвав его метод из себя же, а затем вернувшись в себя, зомби.
Конечно, можно.
Код: Выделить всё
[doj@larion ~/temp]$ cat selfkill.pas
type
TMyObject = class
public
X: LongInt;
procedure Action;
end;
procedure TMyObject.Action;
begin
X := 5;
Writeln('INSIDE ', X);
Free;
Writeln('OUTSIDE');
end;
var
A: TMyObject;
begin
A := TMyObject.Create;
A.Action;
end.
[doj@larion ~/temp]$ fpc -Mdelphi selfkill.pas && ./selfkill
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
INSIDE 5
OUTSIDE
Дож, вижу, что тогда я делаю не так?
И главное как? Как после Free вызывается ещё что то?
И как отловить SIGSEV?
И главное как? Как после Free вызывается ещё что то?
И как отловить SIGSEV?
-
NTFS
- постоялец
- Сообщения: 388
- Зарегистрирован: 05.11.2007 13:57:50
- Откуда: Краснодар
- Контактная информация:
Я бы не стал так делать на Pascal. Слишком велик риск, что рано или поздно, в цепочке методов, управление вернется к черту на рога и система посыпется.
Если нужно удалить объект по его собственной инициативе - лучше использовать исключение из списка без вызова Free. Например, если нужно убрать объект из коллекции родителя, то используем TObjectList.Extract вместо TObjectList.Delete. И память цела, и объект уходит. Да, немного подтекает, но для мелких программ уровня пользователя это некритично, а драйвера/ядра/службы на ООП обычно не делают.
Удачи.
Если нужно удалить объект по его собственной инициативе - лучше использовать исключение из списка без вызова Free. Например, если нужно убрать объект из коллекции родителя, то используем TObjectList.Extract вместо TObjectList.Delete. И память цела, и объект уходит. Да, немного подтекает, но для мелких программ уровня пользователя это некритично, а драйвера/ядра/службы на ООП обычно не делают.
Удачи.
Tango писал(а):Дож, вижу, что тогда я делаю не так?
И главное как? Как после Free вызывается ещё что то?
Я не знаю, я не ориентируюсь в этих 17к строках. В какой строке происходит вызов этого самого Free?
Обычно освобождение делают не сразу внутри всяких обработчиков, как только решили удалить объект, а откладывают удаление на потом и уже в спокойной обстановке где-то в стороне удаляют то, что нужно. Разумеется, если удалить объект и не наложить никакого ограничения на код далее по времени — можно словить AV.
А у меня это делает другой объект, вот и запарывается.
NTFS писал(а):AV - фигня, удаляя объекты в неположенном месте, можно словить такую ошибку, что пробивает все try..except и валит ваше прекрасное приложение на глазах у клиента.
AV — это и есть такая ошибка.
- Лекс Айрин
- долгожитель
- Сообщения: 5723
- Зарегистрирован: 19.02.2013 16:54:51
- Откуда: Волгоград
- Контактная информация:
Не проще ли поставить в объекте переменную, которая просто отмечает объект удаленным?
Tango писал(а):убивается объект TDCLForm
Форма это не просто объект, а объект для работы с окнами. При его удалении могут работать разные алгоритмы, в том числе send/post message. Поэтому даже если форме сделать Free не из собственного метода, можно словить AV.
На дельфях лучше делать как-то так:
Код: Выделить всё
procedure TMyForm.OnClose(Action : TAction);
begin
Action := caFree;
end;
procedyre TMyForm.MyFree;
begin
Close;
end;
Tango писал(а):как отловить SIGSEV?
А чего его ловить? Другой вопрос что он возникает во внутренней кухне LCL, при обращении к удаленной форме.
Добавлено спустя 5 часов 38 минут 34 секунды:
В общем случае не надо пользоваться стандартными методами создания/удаления специализированных объектов. У специализированных объектов часто есть свои, специализированные, функции создания/удаления.
То, что у TForm можно вызвать Create/Destroy - ну это надо похвалить прямые руки разработчиков. В общем случае это не всегда так.
