Когда я использую ссылку Delphi Berlin 10.1 [слабый] (и [небезопасный]), функция «Поддерживает» и «QueryInterface» увеличивают счетчик ссылок, если задана переменная интерфейса, помеченная атрибутом «слабый» (такое же поведение с атрибутом «небезопасно»).Delphi «Поддерживает» увеличивает счетчик ссылок на интерфейсах [слабый] или [небезопасный]
program WeakReferences;
{$APPTYPE CONSOLE}
{$R *.res}
uses System.SysUtils;
type
IAnInterfacedObject = interface
['{351DFDA3-42CA-4A1D-8488-494CA454FD9C}']
end;
TAnInterfacedObject = class(TInterfacedObject, IAnInterfacedObject)
protected
function GetTheReferenceCount : integer;
public
constructor Create;
destructor Destroy; override;
property TheReferenceCount : integer read GetTheReferenceCount;
end;
constructor TAnInterfacedObject.Create;
begin
inherited Create;
writeln('(create AIO instance)');
end;
destructor TAnInterfacedObject.Destroy;
begin
writeln('(destroy AIO instance)');
inherited Destroy;
end;
function TAnInterfacedObject.GetTheReferenceCount : integer;
begin
Result := FRefCount;
end;
procedure WithoutSupports;
var
AIOinstance : TAnInterfacedObject;
AIOinterfaced : IAnInterfacedObject;
[Weak]
WeakAIOinterfaced : IAnInterfacedObject;
begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);
AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);
WeakAIOinterfaced := AIOinstance;
writeln('create WEAK AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;
procedure WithSupports_Weak;
var
AIOinstance : TAnInterfacedObject;
AIOinterfaced : IAnInterfacedObject;
[Weak]
WeakAIOinterfaced : IAnInterfacedObject;
begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);
AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);
Supports(AIOinstance, IAnInterfacedObject, WeakAIOinterfaced);
writeln('create WEAK AIO interfaced with SUPPORTS; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;
procedure WithSupports_Unsafe;
var
AIOinstance : TAnInterfacedObject;
AIOinterfaced : IAnInterfacedObject;
[Unsafe]
UnsafeAIOinterfaced : IAnInterfacedObject;
begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);
AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);
Supports(AIOinstance, IAnInterfacedObject, UnsafeAIOinterfaced);
writeln('create UNSAFE AIO interfaced with SUPPORTS; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;
procedure WithQueryInterface_Weak;
var
AIOinstance : TAnInterfacedObject;
AIOinterfaced : IAnInterfacedObject;
[Weak]
WeakAIOinterfaced : IAnInterfacedObject;
begin
AIOinstance := TAnInterfacedObject.Create;
writeln('created AIO instance; refcount: '+AIOinstance.TheReferenceCount.ToString);
AIOinterfaced := AIOinstance;
writeln('create AIO interfaced; refcount: '+AIOinstance.TheReferenceCount.ToString);
AIOinterfaced.QueryInterface(IAnInterfacedObject, WeakAIOinterfaced);
writeln('create WEAK AIO interfaced with QUERYINTERFACE; refcount: '+AIOinstance.TheReferenceCount.ToString);
end;
begin
try
writeln('--Without "Supports"-------------------');
WithoutSupports;
writeln;
writeln('--With "Supports" - weak-------------------');
WithSupports_Weak;
writeln;
writeln('--With "Supports" - unsafe-------------------');
WithSupports_Unsafe;
writeln;
writeln('--With "QueryInterface" - weak-------------------');
WithQueryInterface_Weak;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
readln;
end.
Что я пропустил здесь? Есть ли функция «WeakSupports»? Является ли это ошибкой или просто недостатком новых «слабых» интерфейсов?
Вот почему я считаю, ARC трудно смешать с не-ARC кода ... так почему я не перешел на ARC для бизнес-кода , и до сих пор сомневаюсь, что когда-нибудь буду использовать компилятор Delphi linux. –
@ArnaudBouchez Я не уверен, что вы имеете в виду. Смешивание ссылок на объекты и проблем с ссылками на интерфейс - это то, что решает ARC-компилятор. Конечно, для кросс-платформенного кода вам все равно придется следовать правилам компилятора, отличным от ARC, и никогда не смешивать эти два. –
Далия, есть веские причины для создания объекта с экземпляром локального объекта, а затем назначить его интерфейсу позже. Мы часто создаем и инициализируем объект и только затем назначаем его интерфейсу. – Graymatter