powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Улучшил FreeAndNil. Можете не благодарить.
25 сообщений из 226, страница 6 из 10
Улучшил FreeAndNil. Можете не благодарить.
    #39954479
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
kealon(Ruslan),

Код: pascal
1.
2.
3.
4.
5.
try
  X.Free;
finally
  X:=nil;
end;


Ошибки обработать по желанию/необходимости.
Free это более старый и ненадёжный костыль, чем FreeAndNil
вот он уже точно нигде не нужен
Какой смысл устраивать себе мазохизм?

когда появился FreeAndNil, на своём первом крупном проекте, я отловил кучу ошибок с помощью него

rgreat
alekcvp
Только в случае FreeAndNil() указатель будет обнулён, а в вашем варианте - нет.
Так это то как раз очень плохо.
Очистка объекта не завершена а указатель уже обнулен.

Мы имеем утечку памяти и все предпосылки к сбою, в случае если если это не до убитый поток или нечто с этим связанное.

и толку вам от ссылки на недобитый объект?
идеальный вариант в этом случае, в подавляющем большинстве вариантов: приложение должно падать с багрепортом.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954483
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
Free это более старый и ненадёжный костыль, чем FreeAndNil
вот он уже точно нигде не нужен

Появление Free обусловлено, скажем так, особенностью языка, когда деструктор может быть вызван у недоконструированного объекта. А появление FreeAndNil обусловлено особенностями некоторых индивидов.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954496
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Метод вообще на мой взгляд не нужен

По поводу "не нужен" я уже высказался выше. Я слышал много таких теорий, практически обо всём. Что исключения не нужны и вредны, например, мне тоже доказывали прямо здесь.

rgreat
по этому на мой обсуждать какой из них лучше это не.более чем разминка для мозга.

Так кто же мешает в рамках разминки для мозга ответить на заданный вопрос?
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954531
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
идеальный вариант в этом случае, в подавляющем большинстве вариантов: приложение должно падать с багрепортом.

Падающее приложение в подавляющем большинстве вариантов максимально далеко от идеала.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954534
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
А бывают
видно тертого у меня вот свои rdm например рушатся так чтобы добивать все что на них раскидано даже если что-то из разложенного при своем разрушении таки выбросило, ибо всякое бывает
Kazantsev Alexey
появление FreeAndNil обусловлено особенностями некоторых индивидов
и пояснялось тут неоднократно, с цитированием некогда причастных
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954714
vavan,

Вы просто в одном месте вешаете Try-Except-on&do и оно уже за всем следит. Можно даже глобально установится свой обработчик.

Но суровые - тёртые колочи, на каждый пшик вешают Try-Except-on&do
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954721
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тертым калачам надо обработчик ошибки писать в зависимости от места.
А не один на всех.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954723
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
Так кто же мешает в рамках разминки для мозга ответить на заданный вопрос?

Да как-то даже душа не лежит в этом рытся. Хорошего решения-то нет.

Обработчик ошибок в нее нормально не встроить, а без этого она в общем виде мне нафиг не нужна.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954725
rgreat,

Ошибка может случится где угодно, в любом месте - в зависимости от погонных условий.

1000 обработчиков велишь пихать? Обработчик нужен чисто - для выявления проблемы, под отладкой можно найти место ошибки (Хотя я сомневаюсь что вы удосужитесь освободить указатель, и нарвётесь на кучу других проблем, и вам это никак не поможет)


На крайняк всегда должен висеть Application.OnException
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954731
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Спасибо за советы, но я как-нибудь сам.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954735
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Да как-то даже душа не лежит в этом рытся. Хорошего решения-то нет.

То есть, Вы дали плохое решение?

rgreat
Обработчик ошибок в нее нормально не встроить, а без этого она в общем виде мне нафиг не нужна.

Это, кстати, довольно характерная черта велосипедов из 22127447 . Для решения простой задачи люди пишут уйму сложного кода, будучи свято уверены в том, что это их эксклюзивное ноу-хау для сложных задач.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954737
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
То есть, Вы дали плохое решение?
То что я дал - это не решение, это его частный случай или даже его часть.

softwarer
Для решения простой задачи люди пишут уйму сложного кода, будучи свято уверены в том, что это их эксклюзивное ноу-хау для сложных задач.
Да пусть пишут. Главное что бы меня это использовать не заставляли.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954862
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сабжевая функция при всей своей относительной полезности и кажущейся безобидности имеет один неприятный сайд-эффект.

Если деструктор дергает обработчик события, из которого идет обращение к переменной класса (довольно распространенная ситуация на самом деле), получаем AV, которого не было при простом вызове Free и последующем занулении. Так что бездумно использовать ее не стоит.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954864
misha mike,

ДезИнформация! Ибо в любом случае ты обнуляешь глобальную переменную, к которой обращаешься из обработчика.

Передавай в обработчик объект this(self) класса, а не обращайся глобально.


Опять проблема функции - не доказана. Доказана кривизна рук.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TTest = class
    procedure Test;
    constructor Create;
    destructor Destroy; override;
    procedure CallHandler(Sender: TObject);
  private
    FOnTest: TNotifyEvent;
  public
    Tick: Integer;
    TestStr: string;
    TestArr: TArray<Integer>;

    property OnTest: TNotifyEvent read FOnTest write FOnTest;
  end;

var
  Form1: TForm1;
  Test1: TTest;

implementation

{$R *.dfm}

procedure TestCallBack(Test1: TTest);
begin
  Test1.OnTest(Test1);
end;

procedure TTest.CallHandler(Sender: TObject);
var
  cl: TTest;
begin
  cl := TTest(Sender);

  for VAR I := Low(cl.TestArr) to High(cl.TestArr) do
  begin
    Tick := (cl.TestArr[I] * 2) - TestArr[I];
  end;
  TestStr := TestStr + Tick.ToString;
end;

procedure TTest.Test;
begin
  TestCallBack(self);
end;

constructor TTest.Create;
begin
  Tick := 0;
  OnTest := CallHandler;

  SetLength(TestArr, Random(100));
  for var I := Low(TestArr) to High(TestArr) do
    TestArr[I] := I * 2;

  TestStr := 'Count := ' + Length(TestArr).ToString;
end;

destructor TTest.Destroy;
begin
  Test;
  ShowMessage(TestStr);
  SetLength(TestArr, 0);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Try
    FreeAndNil(Test1);
  Except
    on E: Exception do
      ShowMessage(E.ClassName + ' ошибка с сообщением : ' + E.Message);
  end;

  if Test1 = nil then
    ShowMessage('Обнулён');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Test1 := TTest.Create;
end;

end.

...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954865
В принципе то мне понятно почему изначально в ОПП обработчиков вкладывался Sender: TObject что бы всегда иметь ссылку на свой класс. Но многие стесняются использовать драгоценный Sender as TClass, и передавать куда угодно, и там же использовать. Не имея ссылок на глобальные переменные класса


Пиля сук на котором стоишь, ты в любом случае роешь себе могилу. И неважно что ты используешь, включая FreeAndNil

Тут как говорится - или рыбку съесть(Передать указатель), или на кол сесть (Всё равно обнулить переменную)
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954876
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
Сабжевая функция при всей своей относительной полезности и кажущейся безобидности имеет один неприятный сайд-эффект.

Если деструктор дергает обработчик события, из которого идет обращение к переменной класса (довольно распространенная ситуация на самом деле), получаем AV, которого не было при простом вызове Free и последующем занулении. Так что бездумно использовать ее не стоит.
так в этом и весь цимес :-)
какой смысл от наполовину разрушенного объекта?

объект пошёл на удаление - нефиг к нему лезть по глобальным переменным, только по эксклюзивному доступу (передавая указатель на себя) подписчикам, собственно как в 22128594
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954892
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
(довольно распространенная ситуация на самом деле)

Тем, у кого она распространена, стоит задуматься о степени служебного соответствия.

misha mike
получаем AV, которого не было при

И хорошо. Это отличная удобная индикация проблемы, которая возникает в 100% случаев, правится за пару минут и при наличии хотя бы минимального тестирования не имеет практических шансов дойти до продакшна. Так гораздо лучше, чем позволить программе рандомное удовольствие работы с внутренностями полуосвобождённых объектов и выгребать ситуации типа "компилирую в debug - всё хорошо, а собираю release - и на проде вываливается проблема".
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954942
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё так. Не существует ни одной причины хранить зомби-ссылки. Как бы тут ни старались убедить в обратном.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954944
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Во-первых, не всегда Sender равен уничтожаемому объекту. Даже в стандартных компонентах это часто инкапсулированный объект, который не факт, что имеет ссылку на хозяина.

А во-вторых, в программах сложнее калькулятора цепочка вызовов из обработчика может может быть очень длинной, и никакой Sender в ее дальний конец уже не передается.

Каждый инструмент имеет свою область применения, FreeAndNil не является универсальным способом уничтожения объекта, точка.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954949
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer
Так гораздо лучше, чем позволить программе рандомное удовольствие работы с внутренностями полуосвобождённых объектов и выгребать ситуации типа "компилирую в debug - всё хорошо, а собираю release - и на проде вываливается проблема".

О каком полуосвобождении идет речь? Вызов обработчика из деструктора -- совершенно нормальная практика. А что будет в обработчике, не всегда известно тому, кто этот обработчик пишет. Там может быть вызов пользовательского скрипта, который не определен на этапе разработки программы.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954950
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon
Всё так. Не существует ни одной причины хранить зомби-ссылки. Как бы тут ни старались убедить в обратном.

А кто говорит про зомби? Пока не отработал деструктор, ссылка остается вполне актуальной.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954958
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
makhaon
Всё так. Не существует ни одной причины хранить зомби-ссылки. Как бы тут ни старались убедить в обратном.

А кто говорит про зомби? Пока не отработал деструктор, ссылка остается вполне актуальной.

Т.е. пока работает деструктор, то объект по этой ссылке можно дёргать из другого потока, например?
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954962
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
misha mike
О каком полуосвобождении идет речь?

О том, которое Вы только что с блеском подтвердили своим тезисом про ссылку на хозяина. Простой пример на пальцах. На форме размещён фрейм, у фрейма прописан обработчик OnDestroy. Суть Вашей претензии: если сделать форме FreeAndNil, то в момент срабатывания обработчика глобальная переменная формы уже будет равна nil и попытка доступа из обработчика к другим компонентам формы закончится AV. Поэтому FreeAndNil мешает адекватному программированию и это плохо, ай-яй-яй. Суть моего тезиса: к моменту срабатывания обработчика форма уже полуразрушена, попытка доступа к компонентам через глобальную переменную способна привести к разнообразным непредсказуемым эффектам работы с мусором, оставшимся в освобождённой памяти. FreeAndNil спасает от подобных проблем и хорошо, а то, что Вы называете распространённой ситуацией - категорически неадекватно.

misha mike
Вызов обработчика из деструктора -- совершенно нормальная практика. А что будет в обработчике, не всегда известно тому, кто этот обработчик пишет. Там может быть вызов пользовательского скрипта, который не определен на этапе разработки программы.

Угу. Таким образом и появляются программы, которые иногда работают. Например, на одной из работ я столкнулся с тем, что подобные авторы боялись перекомпилировать клиента - потому что компиляция из одних и тех же исходников на одном и том же компьютере с вероятностью порядка 2/3 давала очевидно неработоспособный exe (ну то есть тот, в котором находили грубые ошибки в первые пять-десять минут регресса), а с вероятностью порядка 1/5 - на первый взгляд работоспособный exe (тот, в котором не находили ошибок через час-два регресса). И они несколько лет занимались тем, что старались решить все потребности "скриптами", когда этого не удавалось - отбрыкаться от того, чтобы их делать, а когда не удавалось - вносили изменение и после этого гоняли цикл собрать-тестировать-собрать-тестировать-собрать-тестировать, пока очередное ручное тестирование не говорило, что вроде бы релиз получился жизнеспособным.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954964
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

А при чем тут другой поток? Потокобезопасные классы -- это отдельная большая песня. Речь о таком, вполне однопоточном кейсе:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
destructor TConnection.Destroy;
begin
  if FActive then 
    Close;
  ...
  inherited;
end;

procedure TConnection.Close;
begin
  ...
  if Assigned(FOnClose) then
    FOnClose(...);
end;



У нас из деструктора вызывается внешний обработчик OnClose, который вполне может обратиться к переменной, указывающей на экземпляр TConnection, но которая была обнулена вызовом FreeandNil еще до вызова деструктора.
...
Рейтинг: 0 / 0
Улучшил FreeAndNil. Можете не благодарить.
    #39954967
misha mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer, ваш главный тезис "если вызван деструктор, то экземпляр тут же официально считаестя мертвым" корректен лишь отчасти. В случае класса, где из деструктора вызывается обработчик события, логично ожидать, что на момент вызова обработчика класс все еще находится во вменяемом состоянии и к нему можно так или иначе обратиться.

Что касается логики работы FreeAndNil, то она в стремлении не допустить даже кратковременного существования ссылки на мертвый объект, улетает в другую крайность: допускает существование живого и еще работающего объекта при мертвой ссылке. И это тоже неконсистентное состояние программы, хоть и несущее меньше потенциальных проблем.
...
Рейтинг: 0 / 0
25 сообщений из 226, страница 6 из 10
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Улучшил FreeAndNil. Можете не благодарить.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]