Обход (отключения) подсчета ссылок Delphi для интерфейсов

В папке приложения экспорта есть файл Forex.py. Измените строку,

network_input_size = 227 на network_input_size = 224

Затем я перестроил и перезапустил свой док-контейнер, и он заработал.

10
задан onnodb 20 April 2009 в 17:41
поделиться

4 ответа

Хорошо, вы можете обойти это, но вопрос в том, действительно ли вы этого хотите. Если вы хотите использовать интерфейсы, лучше использовать их полностью. Поэтому, испытав это, вы получите проблемы, если смешаете переменные класса и интерфейса.

var
  // DatabaseSettings: TDatabaseSettings; 
  DatabaseSettings : IMySettings;

//Now, in some function...
O := TMyBusinessObject.Create;
O.Settings := DatabaseSettings; 
// ... do something with O
O.Free;

Теперь у вас есть вторая ссылка на интерфейс, и потеря первой не освободит объект.

Также возможно сохранить оба класс и объект:

var
  DatabaseSettings: TDatabaseSettings; 
  DatabaseSettingsInt : IMySettings;

Обязательно установите интерфейс сразу после создания объекта.

Если вы действительно хотите отключить подсчет ссылок, вам просто нужно создать нового потомка TObject, который реализует IInterface. Я протестировал приведенный ниже пример в D2009, и он работает:

// Query Interface can stay the same because it does not depend on reference counting.
function TMyInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GetInterface(IID, Obj) then
    Result := 0
  else
    Result := E_NOINTERFACE;
end;

constructor TMyInterfacedObject.Create;
begin
  FRefCount := 1;
end;

procedure TMyInterfacedObject.FreeRef;
begin
  if Self = nil then
    Exit;
  if InterlockedDecrement(FRefCount) = 0 then
    Destroy;    
end;

function TMyInterfacedObject._AddRef: Integer;
begin
  Result := InterlockedIncrement(FRefCount);
end;

function TMyInterfacedObject._Release: Integer;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result = 0 then
    Destroy;
end;

FreeRef просто понижает рефконт, как _Release. Вы можете использовать его там, где обычно используете Free.

13
ответ дан 3 December 2019 в 14:25
поделиться

Чтобы отключить подсчет ссылок, AddRef и Release не должны делать ничего, кроме возврата -1

function TMyInterfacedObject._AddRef: Integer;
begin
  Result := -1;
end;

function TMyInterfacedObject._Release: Integer;
begin
  Result := -1;
end;

В интерфейсах довольно много утилит без подсчета ссылок. Если вы используете подсчет ссылок, вы не можете смешивать ссылки на объекты и интерфейсы, так как могут случиться плохие вещи. Отключив счетчик ссылок, вы можете с радостью смешивать ссылки на интерфейс и объекты, не беспокоясь о том, что ваши объекты внезапно будут автоматически уничтожены.

4
ответ дан 3 December 2019 в 14:25
поделиться

_AddRef , _Release и _QueryInterface фактически являются , что вы хотите переопределить. Однако вы должны четко понимать, что вы делаете, поскольку это может привести к утечкам памяти или странным, трудно обнаруживаемым ошибкам.

Не спускайтесь с TInterfacedObject , вместо этого спускайтесь с TObject и реализовать свои собственные версии первых двух из тех методов, которые возвращают 1.

7
ответ дан 3 December 2019 в 14:25
поделиться

Отключение подсчета ссылок для такого рода проблем плохо пахнет. Гораздо более приятным и архитектурным решением было бы использование какого-то «синглтонного» паттерна. Самый простой способ реализовать это выглядит следующим образом:

interface 

type

TDatabaseSettings = class(..., IMySettings)
end;

function DatabaseSettings: IMySettings;

implementation

var
  GDatabaseSettings: IMySettings; 

function DatabaseSettings: IMySettings;
begin
 if GDatabaseSettings = nil then GDatabaseSettings := TDatabaseSettings.Create;
 Result := GDatabaseSettings;
end;

O := TMyBusinessObject.Create;
O.Settings := DatabaseSettings; 
O.Free;

Кстати, когда вы используете интерфейсы: всегда используйте переменные интерфейса! Не смешивайте оба интерфейса класса en (используйте «Настройки var: IMySettings» вместо «Настройки var: TDatabaseSettings»). В противном случае подсчет ссылок будет мешать вам (автоматическое уничтожение, недопустимые операции с указателями и т. Д.). В приведенном выше решении GDatabaseSettings также имеет тип «IMySettings», поэтому он получает правильный счетчик ссылок и будет действовать до завершения вашей программы.

3
ответ дан 3 December 2019 в 14:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: