Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Удаление объекта  [new]
ВотЭтоДа
Guest
Делаю FreeAndNil (Для кнопки) и получаю ошибку.

Ошибка просиходит из недр VCL

destructor TControl.Destroy;
begin
  Application.ControlDestroyed(Self);
  if (FHostDockSite <> nil) then
  begin
    FHostDockSite.RemoveFreeNotification(Self);
{$IF DEFINED(CLR)}
    FHostDockSite.UndockClient(nil, Self);
{$ELSE}
    FHostDockSite.Perform(CM_UNDOCKCLIENT, 0, Winapi.Windows.LPARAM(Self));
{$ENDIF}
    SetParent(nil);
    Dock(NullDockSite, BoundsRect);
    FHostDockSite := nil;
  end else
    SetParent(nil);
  FreeAndNil(FActionLink);
  FreeAndNil(FConstraints);
  FreeAndNil(FFont);
{$IF NOT DEFINED(CLR)}
  StrDispose(FText);      ВОТ ТУТ ОШИБКА 
{$ENDIF}
  FreeAndNil(FMargins);
  FCustomHint := nil;
  FreeAndNil(FTouchManager);
  inherited Destroy;
end;


Кто знает почему ? Создаю объект динамикой

К сообщению приложен файл. Размер - 8Kb
10 июн 18, 10:02    [21483190]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
чччД__
Guest
ВотЭтоДа,

ты просто что-то не так делаешь. Если все делать правильно - ошибки не будет.
А если неправильно - ошибка.

Я в магазине как-то выстоял очередь в кассу, хотел расплатиться, но - "ошибка".
И вроде кошелек с собой взял, и все равно - "ошибка".
Так ничего и не купил.
Никто не знает, почему? Зарплата была днем раньше.
10 июн 18, 10:24    [21483218]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
Форма удалялась быстрее (
10 июн 18, 11:09    [21483282]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
Почему я не могу удалить компонент в отдельности? Когда формы уже нет

Ведь в моём случае, этого компонента нету в TForm.Components[idx] он чисто есть на parent

Скорее всего это и баг, в одно и то же время с моим недочётом.

Форму удаляем, удаляем компонент, у компонента parent = nil но мы не можем удалить компонент из за StrDispose(FText);
10 июн 18, 11:36    [21483297]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
Как удалить привязку компонента к форме ??? Именно компонента, потому что вызов Form.DestroyComponents; ничего не даёт.
10 июн 18, 11:52    [21483324]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1063
  Button1.Parent := nil;
  Form1.Free;
  Button1.Free;
10 июн 18, 11:55    [21483329]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
X-Cite,

У меня нет возможности так сделать, сообщение может прилететь и раньше, и позже - я никак не решаю...

Ибо, существуют счётчик ссылок, на форму ссылки кончаются - прилетает сообщение удалить формы.

Опа - ссылки -1 на кнопку, надо и её удалить... И тут баг

Тем более parent уже nil


program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  Windows, System.SysUtils, Vcl.Forms, Vcl.StdCtrls, Vcl.dialogs, Vcl.Controls;

var
  Form: TForm;
  But: TButton;

begin
  try
    Form := TForm.Create(nil);
    Form.Caption := 'Caption';
    But := TButton.Create(nil);
    But.Caption := 'click';
    But.Parent := Form;
    Form.Show;

    FreeAndNil(Form);
    if But.Parent = nil then
    begin
      ShowMessage('Я узе NIL');
      But.Parent := nil;
    end;
    FreeAndNil(But);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
10 июн 18, 12:04    [21483340]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
krapotkin
Member

Откуда: Екатеринбург
Сообщений: 608
а что, бывает {$APPTYPE CONSOLE} и Form := TForm.Create(nil); ?

если у вас компонент создан с указанием владельца, то его можно НЕ удалять при разрушении формы
если нужно его удалить раньше, то никаких проблем в VCL в отличии от FMX, нет
только как и всегда, прибегайте к FreeAndNil
10 июн 18, 13:06    [21483377]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10301
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Vcl.Controls.TControl.Parent
Note: The Parent property declared in TControl is similar to the Owner property declared in TComponent, in that the Parent of a control frees the control just as the Owner of a component frees that component
10 июн 18, 13:14    [21483386]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
Олег Третьяков
Member

Откуда: Волгоград
Сообщений: 151
ВотЭтоДа,
But := TButton.Create(Form);

Не спасет отца русской демократии?!
10 июн 18, 13:16    [21483389]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
Олег Третьяков,

Не спасала..


Убрал удаление формы, и в конец программы всунул (Удаляем всё что создали сами - удаляем самым последним - формы)
for idxObj := 0 to ObjectListCount do
begin
  ObjectCurrP := @ObjectList[idxObj];
  for IdxObj2 := 0 to ObjectCurrP^.listCurr do
  begin
    ObjectDelphiCurr := TObject(ObjectCurrP^.list[IdxObj2].obj);
    if (ObjectDelphiCurr <> nil) and ObjectCurrP^.list[IdxObj2].NotFree then
    begin
      if not ObjectDelphiCurr.InheritsFrom(TApplication) and
        not ObjectDelphiCurr.InheritsFrom(TScreen) and
        not ObjectDelphiCurr.InheritsFrom(TForm) then
      begin
        ObjectDelphiCurr.Free;
        ObjectCurrP^.list[IdxObj2].NotFree := False;
      end;
    end;
  end;
end;

for idxObj := 0 to ObjectListCount do
begin
  ObjectCurrP := @ObjectList[idxObj];
  for IdxObj2 := 0 to ObjectCurrP^.listCurr do
  begin
    ObjectDelphiCurr := TObject(ObjectCurrP^.list[IdxObj2].obj);
    if (ObjectDelphiCurr <> nil) and ObjectCurrP^.list[IdxObj2].NotFree then
    begin
      if not ObjectDelphiCurr.InheritsFrom(TApplication) AND
        not ObjectDelphiCurr.InheritsFrom(TScreen) then
        ObjectDelphiCurr.Free;
    end;
  end;
  SetLength(ObjectCurrP^.list, 0);
end;
SetLength(ObjectList, 0);

ListObjectId.Free;
10 июн 18, 13:44    [21483414]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1063
    But.Parent := Form;
    Form.Show;

    FreeAndNil(Form);
    if But.Parent = nil then

Типичная ошибка новичка...
У вас But уже битый указатель указывает на область памяти уничтоженного объекта. Кнопки уже нет. Просто пока память не перезатерлась и вроде создается имитация работы.
But.Parent := Form; собственно задает кнопке владельца форму и кнопка будет уничтожена при уничтожении формы.

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  Windows, System.SysUtils, Vcl.Forms, Vcl.StdCtrls, Vcl.dialogs, Vcl.Controls;

var
  Form: TForm;
  But: TButton;

type
  TButtonEx = class(TButton)
  public
    destructor Destroy; override;
  end;

{ TButtonEx }

destructor TButtonEx.Destroy;
begin
  ShowMessage('Неожиданно, да?');
  inherited;
end;

begin
  try
    Form := TForm.Create(nil);
    Form.Caption := 'Caption';
    But := TButtonEx.Create(nil);
    But.Caption := 'click';
    But.Parent := Form;
    Form.Show;

    FreeAndNil(Form);
    if But.Parent = nil then
    begin
      ShowMessage('Я узе NIL');
      But.Parent := nil;
    end;
    FreeAndNil(But);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


Как вы думаете что раньше вызовается? Деструктор кнопки или проверка на nil зомби переменной?
10 июн 18, 13:46    [21483421]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
чччД__
Guest
for idxObj := 0 to ObjectListCount do

ObjectListCount - чему равен?
10 июн 18, 13:47    [21483424]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
чччД__,

-1

SetLength(ObjectList, 10000);
ObjectListCount := -1;


Так как
var
  Id: integer;
begin
  if ListObjectId.TryGetValue(Ed.This.obj.Handle, Id) then
    Result := ObjectList[LOWORD(Id)].list[HiWord(Id)].obj
  else
    Result := nil;
end;
10 июн 18, 13:52    [21483434]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
чччД__
Guest
чччД__
for idxObj := 0 to ObjectListCount do

ObjectListCount - чему равен?

ВотЭтоДа
чччД__,

-1
...
Так как ...


"Когда вы говорите, Иван Васильевич, такое впечатление, что вы бредите" - (с).
10 июн 18, 13:57    [21483446]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
чччД__,

Там имелось введу реальный count
10 июн 18, 14:01    [21483453]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
чччД__
Guest
ВотЭтоДа
...Там имелось введу...

Ты можешь просто ответить - чему равно значение верхнего ограничения счетчика при входе в цикл?
чччД__
for idxObj := 0 to ObjectListCount do

ObjectListCount - чему равен?
10 июн 18, 14:05    [21483459]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
чччД__,

Сколько создал объекту, тому и ровна.


К примеру создал TForm ровна 0 обратился к свойству font у TForm она уже +1 так как туда попал класс TFont и так далее. Класс TFont оно не может удалить из за свойства NotFree
10 июн 18, 14:16    [21483472]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
Олег Третьяков
Member

Откуда: Волгоград
Сообщений: 151
ВотЭтоДа
Не спасала..
Убрал удаление формы, и в конец программы всунул (Удаляем всё что создали сами - удаляем самым последним - формы)

И на фига?!
Форма - наследник TComponent и кнопка - наследник TComponent
У кнопки будет владелец - форма.
Форма и удалит кнопку в момент собственной смерти.
Так что все обращения к кнопке после FreeAndNil(Form) - убрать. Это же очевидно.
Может стоит книжки почитать?
10 июн 18, 14:20    [21483476]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
чччД__
Guest
чччД__
for idxObj := 0 to ObjectListCount do

ObjectListCount - чему равен?

ВотЭтоДа
...
Сколько создал объекту, тому и ровна.
...


С русским у тебя так себе, но предположу, что значение ObjectListCount равно числу объектов.
Теперь скажи - сколько раз отработает твой цикл for?
10 июн 18, 14:21    [21483477]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
ВотЭтоДа
Guest
чччД__,

Работает как надо.

ObjectListCount = 3
ObjectList = 4 (3)

И того, как цикл достигнет 4 то он выйдет. И дело сделано.

К сообщению приложен файл. Размер - 41Kb
10 июн 18, 14:27    [21483485]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
defecator
Member

Откуда:
Сообщений: 39475
Чота название на скриншоте какое-то пафосное - NewRttiSuper , а код 21483340 смешной

1. нельзя создать TForm без наличия DFM, надо использовать TCustomForm
2. в коде обращение к убитой перед этим переменной But

тут 21483485 цикл должен идти от нуля до ObjectListCount-1, а не как у тебя

короче, учи матчасть (с)
10 июн 18, 14:57    [21483518]     Ответить | Цитировать Сообщить модератору
 Re: Удаление объекта  [new]
чччД__
Guest
...может, это наш оптимизатор, но под грибами? :)
10 июн 18, 15:03    [21483527]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить