powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Передача reference to function (): Boolean в другой класс
9 сообщений из 9, страница 1 из 1
Передача reference to function (): Boolean в другой класс
    #40009354
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги. Я перескочил с Delphi 5.5 на C# очень давно и поэтому не могу считаться опытным программистом на Delphi 10.2 Tokyo и в связи с этим идиотский вопрос.

Есть класс

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Type
  TBlotterModel_InplacePersonContact = Class (TBlotterModelBase<TPersonContactListItem>, IBlotterInplacePersonContact)
  Private
     _canCommandUpdate: TCommandBoolFunction;
  protected
    function CanCommandUpdate: boolean; override;
    procedure ModelConstructor; override;
  Public
  End;

implementation
Procedure TBlotterModel_InplacePersonContact.ModelConstructor;
begin
  Inherited;
  cctx.Bind_<IBlotterInplacePersonContact>('IBlotterInplacePersonContact', Self);
  _canCommandUpdate := cctx.Get_<TCommandBoolFunction>('CanCommandUpdate');
end;

function TBlotterModel_InplacePersonContact.CanCommandUpdate: boolean;
begin
  Result := Assigned(_canCommandUpdate) and _canCommandUpdate();
end;



Где TCommandBoolFunction = reference to function: boolean, которую кладет ИНОЙ класс в КлиентКонтекст (cctx).

Так вот порядок гибели классов рандомный. Знаю что если ИНОЙ класс положит в клиентконтекст интерфейс и 100 раз подряд погибнет раньше, чем, например, этот, то _myInterface := nil - иногда приведет к AccessViolation. Поэтому чтобы не писать оповещение дочерних классов, от ИНОГО класса, который положил в клиентконтекст интерфейс, я использую директиву [WEAK], которая подразумевает что интерфейс этот есть слабосвязанная ссылка.

А вот что будет с reference to function: boolean полученной от другого класса. Delphi автоматически при уничтожении ИНОГО класса здесь установит _canCommandUpdate := nil. Будет ли для reference to function: boolean работать директива WEAK?


Или вот этот код ИНОГО класса даже при вызове деструктора, обвязанный интерфейсом продолжит свое существование. Именно он передается в клиентконтекст.


Код: pascal
1.
2.
3.
4.
5.
6.
function TModel_PersonNew.CanCommandUpdateContact: Boolean;
begin
  Result := not IsReadOnly and Assigned(BlotterContact.Selected) and
  (BlotterContact.SelectedRows.Count = 1) and ((BlotterContact.Selected.Cont_Type = TDBConst.GetInstance.GetPerson('PSN_CONTACT_PHONE_CLIENT'))
   or (BlotterContact.Selected.Cont_Type = TDBConst.GetInstance.GetPerson('PSN_CONTACT_EMAIL_MAIN')))
end;
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009358
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделал тест.

Код: 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.
unit BlotterModel_F405;

interface

uses Windows, SysUtils, _ClassBlotterModelBase, F405ListItem;

Type
  TBlotterModel_F405 = Class (TBlotterModelBase<TF405ListItem>)
  protected
    procedure ModelConstructor; Override;

  End;

  TTestClass = class
  private
    FCOunt: Integer;
  public
    constructor create();
    Destructor Destroy; Override;
    function S: Integer;
  end;

  TIntFunc = reference to function: Integer;

implementation

uses _classmessageBrokerHelper, intfStatusWriter, dialogs;

{ TBlotterModel_F405 }

procedure TBlotterModel_F405.ModelConstructor;
var i: integer;
    t: TTestClass;
    [WEAK] f: TIntFunc;
begin
  inherited;
  t := TTestClass.create;
  f := t.S;
  for i := 1 to 1000 do
    f();
  t.Free;

  for i := 1 to 1000 do
    if assigned(f) then
      f();

end;

{ TTestClass }

constructor TTestClass.create;
begin
  FCount := 1000;
end;

destructor TTestClass.Destroy;
begin
  ShowMessage('Destroy');
  inherited;
end;

function TTestClass.S: Integer;
begin
  Randomize;
  Result := Random(FCount);
end;

end.



Деструктор класса TTestClass вызывается как положено. F - не получает nil, несмотря на то что указана директива [WEAK].
Так что получается: FCount захвачена в контекст, обвязанный интерфейсом. Или все-таки FCount ссылается на мертвую память?
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009360
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проверил - адрес поля FCount после конструирования TTestClass, в методе F() и еще раз в методе F() после вызова деструктора одинаковый.

Или я что-то глобально упускаю. Или все-таки придется метод передавать интерфейсом явно.
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009365
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все разобрался. Придется реализовать интерфейсами с директивой WEAK.
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009368
zedxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mixrud, Я так понимаю, weak просто не поддерживается для анонимных методов?
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009369
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zedxxx,

Похоже только работает с интерфейсами. По крайней мере у меня на проде уже много интерфейсов с [WEAK] и проблем пока нет.
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009473
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud,

Всегда было правило, что подписчик должен отменить подписку перед своей гибелью. И это правило актуально для любого языка
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009494
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_,

Тема про то что подписку хотелось увидеть автоматическую. Это слой контроллеров модели паттерна MVVM. Негоже в нем заниматься явными подписками. Ибо это код относящийся к системному программированию, а в этом слое программист должен заниматься обёрткой бизнес сущности.
...
Рейтинг: 0 / 0
Передача reference to function (): Boolean в другой класс
    #40009765
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud
подписку хотелось увидеть автоматическую.
Автоматического ничего не бывает. То, что выглядит автоматическим на одном слое, реализовано алгоритмически на нижестоящем слое
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Передача reference to function (): Boolean в другой класс
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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