Перейти к содержанию
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 пользователей онлайн

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