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

DisposeOf или Free?


DMS

Вопрос

Вопрос про мобильные системы. Разброд и шатания.

Вот на этой странице схожие примеры, но один оканчивается DisposeOf, а другой Free.

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Mobile_Tutorial:_Using_Notifications_(iOS_and_Android)

procedure TForm1.RepeatedNotificationClick(Sender: TObject);
var
  MyNotification: TNotification;
begin
  MyNotification := NotificationCenter1.CreateNotification;
  try
    MyNotification.Title := 'MyNotification';
    MyNotification.AlertBody := 'Repeating notification each minute!';
    //Fired in 10 seconds
    MyNotification.FireDate := Now + EncodeTime(0, 0, 10, 0);
    //Repeated each minute
    MyNotification.RepeatInterval := TRepeatInterval.Minute;
    // Send notification to the notification center
    NotificationCenter1.ScheduleNotification(MyNotification);
  finally
    MyNotification.Free;
  end;
end;

 

procedure TForm1.ScheduleNotificationClick(Sender: TObject);
var
  MyNotification: TNotification;
begin
  MyNotification := NotificationCenter1.CreateNotification;
  try
    MyNotification.Name := 'MyNotification';
    MyNotification.AlertBody := 'Delphi for your mobile device is here!';
    // Fired in 10 seconds
    MyNotification.FireDate := Now + EncodeTime(0, 0, 10, 0);
    // Send notification to the notification center
    NotificationCenter1.ScheduleNotification(MyNotification);
  finally
    MyNotification.DisposeOf;
  end;
end;

 

Ссылка на комментарий

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

  • 0
  • Модераторы
  • 0

Вот эту еще почитайте статью, мне она больше понравилась.

http://www.gunsmoker.ru/2013/05/modern-delphi.html

Проблема DisposeOf в том, что он не освобождает память, а просто вызывает деструктор (к классу потом можно обратиться, и не будет Access Violation).

На моб. платоформах я обычно иcпользую Free как и раньше, иногда FreeAndNil (если необходимо) т.к. на моб. платформах в отличии от десктопных платформ, вызов Free работает по другому . Если зайти в тело метода там будет комментарий: 

// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear

В случае моб. платформ - Free обнуляет переменную, уменьшает ARC на единицу, затем проверяет счетчик ARC и если он = 0 - то вызывает деструктор. 

Если объект где то присваивался, в какую либо еще переменную, и переменная не была обнулена, то его счетчик ссылок ARC > 0, то он не освободиться с вызовом Free, на эту тему есть баг (фича?) с reference procedure, который вроде уже исправили в Токио (я не проверял, т.к. пока токио нормально не работает под Android).

А вот в случае с визуальными контролами, если нужно убрать контрол, надо использовать DisposeOf  иначе он останется на форме (может кто знает как его убрать при помощи Free, что и где обнулить? ).

Изменено пользователем ENERGY
Ссылка на комментарий
  • 0

для всех. если RefCount=0 то он уничтожится

перед удалением компонента посмотрите его RefCount

потом сделайте ему parent:=NIL; посмотрите опять

потом FreeAndNIl. чтобы было понятно

Ссылка на комментарий
  • 0

Непонятно только, почему на одной странице приводятся примеры, в одном случае DisposeOf, в другом - Free. Примеры писали разные люди? Какая-то несогласованность, имхо.

Такого бардака в документации, например, Майкросоофта нет.

Ссылка на комментарий
  • 0

Согласно учениям великого кормчего Allen Bauer, использование счетчика ссылок это великое достижение мировой цивилизации и гигантский шах человечества на пути ко всеобщему счастью. По этому всегда и везде надо использовать Free или FreeAndNil. Но при этом не забывать про сильные и слабые ссылки. Чаще всего, если какое-то поле класса — экземпляр объекта который создается и разрушается строго внутри этого класса, то это сильная ссылка (по умолчанию), если поле нужно только для хранения ссылки на некоторый внешний экземпляр объекта, то эта слабая ссылка (должна быть директива [weak]). Это нормально работает когда, например объект A хранит ссылку на объект B, но при этом B ни чего не знает про A.

type

TA = class
private
  [weak] FB: TB;
public
  constructor Create(B: TB);

Если не поставите [weak], Вы не сможете удалить объект B до тех пор пока не удалите объект A, либо не обнулите поле FB (а вы его не обнулите, поскольку это приватное поле). Разумеется контроль weak`ов остается на совести программиста. Т.к. формально утечек памяти нет, ссылка-то есть а объекте A, и в момент завершения работы приложения, объект А, и объект B обязательно "честно" удаляться. Просто объект B будет тихохонько сидеть в памяти и ни кого не беспокоить (правда удобно :o)
Проблема наступает, если вдруг вам посчастливилось и в объекте B сделать ссылку на объект A. Тогда конечно вы не сможете удалить объект A пока не удалите объект B (см. предыдущий абзац).
Обычно всё можно списать всё на "кривость" архитектуры и необходимость исключить перекрестные ссылки. Но вот беда, таких мест, где A ссылается на B, а B ссылается на A очень много, на этом основана вся компонентная архитектура Delphi, на которую ни кто особо не жаловался предыдущие 20 лет. Каждый компонент содержит ссылку на Owner, а Owner содержит список ссылок на все компоненты, которыми владеет. Вот чтобы как-то можно было удалить какой-то компонент придуман метод DisposeOf, он разрушает объект игнорируя все "прелести" счетчика ссылок. Это конечно не эстетично, зато надежно, дешево, практично.
Так что вывод такой, что везде, где возможно делаем Free и [weak], а где невозможно DisposeOf.

Ссылка на комментарий
  • 0
2 часа назад, krapotkin сказал:

зато новый геморрой)) при выходе из программы )

DisposeOf сделали, а потом Owner как давай обращаться к этому компоненту ))

Не, это геморрой старый. Наличие подсчета ссылок ни как его не уменьшает. Решается он путем TComponent.FreeNotification.

Вся "прелесть" решения в том, что Free работает не так как раньше работал Free, а DisposeOf теперь работает так же как раньше работал Free. На десктопных платформах всё как раньше, а вот на мобильных, надо помнить, что за каждым углом тебя поджидает ARC с дубиной.

FreeNotification и ARC по сути два разных механизма для решения одной проблемы, которые частично дублируют друг друга, частично конфликтуют, как два антивируса на одном компе. кактотак

Ссылка на комментарий
  • 0

 

Цитата

Вся "прелесть" решения в том, что Free работает не так как раньше работал Free, а DisposeOf теперь работает так же как раньше работал Free. 

@RoschinSpb

Ну нет же.

В не ARC (Auto reference counter), классическом компиляторе (Windows и Mac)  Free всегда вызывает деструктор и освобождает память выделенную под класс и его поля. Т.е. если обратиться потом к такому классу произойдет исключение AV.

А вот в ARC компиляторах, DisposeOf вызовет деструктор, но память выделенная под класс и его поля, останется занятой, и не освободиться. Т,е. если после DisposeOf обратится к полям класса, не будет исключения AV, но поля уже будут очищены.  При этом в деструкторе можно освободить свои данные и уничтожить инкапсулированные классы.

Такие объекты называют зомби-объекты - т.к. они остаются висеть в памяти до конца работы программы, и даже если ссылка позже на него уменьшиться до 0, память не освободиться и деструктор не будет вызван повторно.  Чтобы узнать находится ли объект в зомби состоянии, есть метод Disposed - это аналог Assign.

Повторюсь всем рекомендую статью GunSmoker, там эта тема хорошо освещена.

 

Изменено пользователем ENERGY
Ссылка на комментарий
  • 0
1 час назад, ENERGY сказал:

если после DisposeOf обратится к полям класса, не будет исключения AV, но поля уже будут очищены...

Повторюсь всем рекомендую статью GunSmoker, там эта тема хорошо освещена.

 

Да, всё гораздо веселее :unsure: чем я описал в первом приближении.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

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