Я работаю над проектом, где я имею сопрягаемую TRectangle, как это:Избавление сопрягаемого объекта с ARC против без - Delphi
IBoardShape = interface(IInterface)
function GetColor: integer;
procedure SetColor(const aColor: integer);
property Color: integer read GetColor write SetColor;
end;
TGameRectangle = class(TRectangle, IBoardShape)
private
FColor: integer;
procedure SetColor(const aColor: integer);
function GetColor: integer;
property Color: integer read GetColor write SetColor;
protected
{$IFNDEF AUTOREFCOUNT}
[Volatile] FRefCount: Integer;
{$ENDIF}
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
_AddRef
и _Release
такого же, как в InterfacedObject
:
function TGameRectangle._AddRef: Integer;
begin
{$IFNDEF AUTOREFCOUNT}
Result := AtomicIncrement(FRefCount);
{$ELSE}
Result := __ObjAddRef;
{$ENDIF}
end;
function TGameRectangle._Release: Integer;
begin
{$IFNDEF AUTOREFCOUNT}
Result := AtomicDecrement(FRefCount);
if Result = 0 then
Destroy;
{$ELSE}
Result := __ObjRelease;
{$ENDIF}
end;
Чтобы создать прямоугольник, что я делаю это:
var
lRect: TGameRectangle;
begin
lRect := TGameRectangle.Create(self);
lRect.Parent := Layout1;
lRect.Align := TAlignLayout.alClient;
FIntObj := lRect as IBoardShape;
Позже я бесплатно его, установив FIntObj
на номер nil
. В Windows, когда я следую _Release
, счетчик ссылок равен 1, и счетчик уменьшается и объект освобождается. При работе в Android количество ссылок составляет 5, когда я вхожу в _Release
(счетчик ссылок отображается внутри __ObjRelease
). Поскольку счетчик ссылок по-прежнему высок, объект не освобождается.
Я воссоздал это в простой демонстрации, используя в основном только код, который я разместил здесь. Может ли кто-нибудь объяснить, что отличается в ARC, что приводит к тому, что счетчик ссылок настолько высок?
При работе с ARC ** каждая ** ссылка на экземпляр увеличивает RefCount. Вы передаете Владельца и родителя, и оба они держат ** ** ** ссылку на этот экземпляр. Кроме того, ссылка на интерфейс у вас минимум 3 - но есть, конечно, больше ссылок, вызванных владельцем и родителем. –
@SirRufo ... если вы не используете ссылку '[weak]', которая необходима, например. для круговых ссылок. См. Статью [Марко] (http://blog.marcocantu.com/blog/automatic_reference_counting_for_delphi.html). ИМХО такое нарушение изменений модели памяти Delphi было одной из худших идей когда-либо. –
@ArnaudBouchez Delphi слишком боится изменений, особенно нарушая изменения. Я стремлюсь к появлению ARC для настольного компилятора. Нет ничего плохого в использовании атрибута '[слабый]'. –