Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как сделать отложенное удаление компонента из обработчика его же события?


Igor

Вопрос

Опубликовано (изменено)

Т.е. допустим кликнул я на сферу, и она должна удалиться, удаляя её в её же событии OnClick я естественно получаю ошибку. Судя по всему нужно передать управление другому обработчику и удалить оттуда, но как грамотно это оформить в FireMonkey?

 

Для VCL нашёл такой способ:

const 

   WM_KILL_CONTROL = WM_USER+ 66; 
type 
  TForm1 = class(TForm) 
  ... 
  private 
    procedure WMKillControl(var msg:TMessage); message WM_KILL_CONTROL; 
.... 
procedure TForm1.WMKillControl(var msg: TMessage); 
var 
  c : TControl; 
begin 
  c := TControl(msg.LParam); 
  if not Assigned ( c ) then 
    Exit; 

  c.Free; 
  windows.MessageBeep($FFFFFFFF); 
end

procedure TForm1.Button1Click(Sender: TObject); 
begin 
  //   Sender.Free;   // würde meistens eine Exception auslösen 
  PostMessage(Self.Handle, WM_KILL_CONTROL, 0, Integer(Sender)); 
end;

 

Есть ли у FMX какой-то свой способ работающий под iOS как эти работают из чужого обработчика: 

c[r].DisposeOf;
c[r] := nil;

и

c[r].Parent := nil;
c[r].Free;
c[r] := nil;

?

 

Метод Release насколько я понял это аналог Free, только отложенный; а как показала личная практика, на XE7 просто Free в мобильном приложении не достаточен, соответственно Release вероятно тоже или я ошибаюсь? (ещё не успел проверить)

Изменено пользователем Brovin Yaroslav

Рекомендуемые сообщения

  • 0
  • Администраторы
Опубликовано

Метод Release является аналогом метода Free, но он вместо Free использует DisposeOf. Это означает, что при любом текущем раскладе с количеством ссылок на этот объект форсируется вызов деструктора.

Асинхронных сообщений нету. Поэтому используйте метод Release с предварительным удалением объекта из всех временных списков. 

  • 0
Опубликовано

Использую Release и получаю ошибку:

post-365-0-23029200-1412627474.png

 

пишу просто:

 text3d3.Release;

пишу:

 text3d3 := nil;
 text3d3.Release;

пишу:

 text3d3.Parent := nil;
 text3d3 := nil;
 text3d3.Release;

без разницы.

 
Я ведь правильно понял про временные списки, имеются ввиду как раз:
 text3d3.Parent := nil;
 text3d3 := nil;

?

  • 0
  • Администраторы
Опубликовано

Это ошибка 3D контрола в FMX. В коде TControl3D пропущена проверка на не пустой Context. Context сбрасывается в момент Parent := nil.

 

Поэтому Release для 3D объектов не подойдет до исправления.  Для 2D объектов Release работает корректно.

 

В итоге, удалить можно:

  1. Либо в OnMoseUp
  2. Либо использовать TTimer для этого. Или вспомогательную обертку, для более удобного удаления объектов подобным способом.

P.S. Ошибку уже исправил.

Гость
Эта тема закрыта для публикации ответов.
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...