在我的代码中,我使用了一个小型数据存储类,它在不同的地方创建.为了避免内存泄漏并简化操作,我想使用引用计数,所以我做到了
type TFileInfo = class (TInterfacedObject, IInterface)
Run Code Online (Sandbox Code Playgroud)
并删除了我对TFileInfo.Free的所有手动调用.不幸的是Delphi报告了很多内存泄漏.搜索SO我发现以下问题解释了为什么这不起作用:
这里有一个解决方法,但它需要我(至少如果我做对了)编写一个自定义接口IFileInfo并为它提供了许多getter和setter,我想避免它.
编辑我应该补充一点,我将创建的FileInfo对象插入到两种不同类型的哈希表中:一个来自TBucketList,另一个是来自Codegear论坛的哈希映射实现.在内部它们都是用户指针,因此情况就像在另一个问题中一样.
还有其他可能使Delphi中的对象使用引用计数吗?
我正在实现我的IDropTarget
基础:如何在不处理Windows消息的情况下允许表单接受文件丢弃?
David 的实施工作正常.但是IDropTarget
(TInterfacedObject
)对象不会自动释放,即使设置为'nil'也不会.
部分代码是:
{ TDropTarget }
constructor TDropTarget.Create(AHandle: HWND; const ADragDrop: IDragDrop);
begin
inherited Create;
FHandle := AHandle;
FDragDrop := ADragDrop;
OleCheck(RegisterDragDrop(FHandle, Self));
//_Release;
end;
destructor TDropTarget.Destroy;
begin
MessageBox(0, 'TDropTarget.Destroy', '', MB_TASKMODAL);
RevokeDragDrop(FHandle);
inherited;
end;
...
procedure TForm1.FormShow(Sender: TObject);
begin
Assert(Panel1.HandleAllocated);
FDropTarget := TDropTarget.Create(Panel1.Handle, nil) as IDropTarget;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
FDropTarget := nil; // This should free FDropTarget
end;
var
NeedOleUninitialize: Boolean = False;
initialization
NeedOleUninitialize := Succeeded(OleInitialize(nil)); …
Run Code Online (Sandbox Code Playgroud) 我有两个单位,第一个,我的界面:
use personas
interface
type
Tllave = array[0..31] of byte;
Tdatos = array of byte;
ImyInterface = interface(IInterface)
function nombre : string;
function edad : integer;
procedure resetear;
function Proceso(datos : tdatos; cantidad : integer) : integer ;
procedure Iniciar(llave : Tllave);
end;
Run Code Online (Sandbox Code Playgroud)
第二单元,我的对象声明:
use militares
interface
uses personas;
type
Tmilitares = Class(TInterfacedObject, ImyInterface )
public
function nombre : string;
function edad : integer;
procedure resetear;
function Proceso(datos : Tdatos; cantidad : integer) : integer ;
procedure Iniciar(llave : Tllave); …
Run Code Online (Sandbox Code Playgroud) 我试图声明一个自定义的接口列表,我想继承它以获取特定接口的列表(我知道IInterfaceList,这只是一个例子).我正在使用Delphi 2007,因此我无法访问实际的泛型(可惜我).
这是一个简化的例子:
ICustomInterfaceList = interface
procedure Add(AInterface: IInterface);
function GetFirst: IInterface;
end;
TCustomInterfaceList = class(TInterfacedObject, ICustomInterfaceList)
public
procedure Add(AInterface: IInterface);
function GetFirst: IInterface;
end;
ISpecificInterface = interface(IInterface)
end;
ISpecificInterfaceList = interface(ICustomInterfaceList)
function GetFirst: ISpecificInterface;
end;
TSpecificInterfaceList = class(TCustomInterfaceList, ISpecificInterfaceList)
public
function GetFirst: ISpecificInterface;
end;
Run Code Online (Sandbox Code Playgroud)
TSpecificInterfaceList将无法编译:
E2211'GetFirst'声明与接口'ISpecificInterfaceList'中的声明不同
我想我理论上可以使用TCustomInterfaceList,但我不想每次使用时都要使用"GetFirst".我的目标是拥有一个特定的类,它继承基类的行为并包装"GetFirst".
我怎样才能做到这一点?
谢谢!
我有一个基于TInterfacedObject的类.我将它添加到TTreeNode的Data属性.
TFacilityTreeItem=class(TInterfacedObject)
private
m_guidItem:TGUID;
m_SomeOtherNode:TTreeNode;
public
end;
Run Code Online (Sandbox Code Playgroud)
我创建了这个对象的许多实例,并假设因为它们被引用计数,我不需要释放它们.那会很方便.
但是,在检查时,我打开了ReportMemoryLeaksOnShutdown,发现它们毕竟没有被释放.
这些对象是在放置在主窗体上的框架中创建的.在主窗体的FormClose中,我清除树节点,以便释放每个对象.
发生了什么?
谢谢您的帮助!
和线程安全吗TInterfacedObject._Release
?TInterfacedObject._AddRef
我可以看到FRefCount
它是线程安全的,但Destroy
不受锁或其他东西的保护。
function TInterfacedObject._Release: Integer;
begin
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
end;
Run Code Online (Sandbox Code Playgroud)
不同的线程Destroy
同时执行是否会导致竞争条件?
我在这种Destroy()
从未被调用的情况下运行。
unit Unit2;
interface
type
// Interface
ITest = Interface(IInterface)
function IsTrue() : Boolean;
end;
TmyClass = class(TInterfacedObject, ITest)
public
// Interface implementation
function IsTrue() : Boolean;
constructor Create();
destructor Destroy(); override;
end;
implementation
constructor TmyClass.Create();
begin
inherited Create();
end;
destructor TmyClass.Destroy();
begin
inherited Destroy();
end;
published
// Property
property IsItTrue: Boolean read IsTrue;
end.
Run Code Online (Sandbox Code Playgroud)
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
Vcl.Dialogs, Vcl.StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: …
Run Code Online (Sandbox Code Playgroud)