我正在尝试制作事件处理程序列表,其中handler是方法引用.要删除特定的处理程序,我需要在列表中找到它.但是我如何比较两个方法引用的代码地址?
type
TEventHandler = reference to procedure;
procedure TestProc;
begin
end;
procedure TForm26.FormCreate(Sender: TObject);
var
Handlers: TList<TEventHandler>;
begin
Handlers := TList<TEventHandler>.create;
try
Handlers.Add(TestProc);
Handlers.Remove(TestProc); { doesn't work }
Assert(Handlers.Count=0); { fails }
Assert(Handlers.IndexOf(TestProc)>=0); { fails }
finally
FreeAndNil(Handlers);
end;
end;
Run Code Online (Sandbox Code Playgroud)
TList <>的默认比较器不能正确比较方法引用.我该如何比较它们?是否存在类似于TMethod的结构,但是方法参考?
你能在TDictionary中使用记录作为Key值吗?我想基于字符串,整数和整数的组合来查找对象.
TUserParKey=record
App:string;
ID:integer;
Nr:integer;
end;
Run Code Online (Sandbox Code Playgroud)
...
var
tmpKey:TUserParKey;
tmpObject:TObject;
begin
tmpObject:= TTObject.Create(1);
tmpKey.App:='1';
tmpKey.ID :=1;
tmpKey.Nr :=1;
DTUserPars.Add(tmpKey,tmpObject)
Run Code Online (Sandbox Code Playgroud)
...
var
tmpKey:TUserParKey;
begin
tmpKey.App:='1';
tmpKey.ID :=1;
tmpKey.Nr :=1;
if not DTUserPars.TryGetValue(tmpKey,Result) then begin
result := TTObject.Create(2);
end;
Run Code Online (Sandbox Code Playgroud)
这返回对象2.
我刚刚开始使用Delphi Spring Framework,并想知道当前版本的DI容器是否允许将构造委托给工厂方法而不指定实现类型?
例如类似的东西:
GlobalContainer
.RegisterFactory<ISomeObject>(
function: ISomeObject
begin
Result := CreateComObject(CLASS_SomeObject) as ISomeObject;
end)
.Implements<ISomeObject> // could probably be implied from the above
.AsSingletonPerThread;
Run Code Online (Sandbox Code Playgroud)
如您所见,我的具体用例是COM对象的实例化.在这种情况下,实现我感兴趣的接口的类不是我的应用程序的一部分,但我仍然可以通过调用CreateComObject/ 来创建实例CoCreateInstance.但是,似乎我运气不好,因为Container中的注册似乎总是绑定到实际的实现类.
假设目前不可能这样做,那么你们的专家怎么解决这个问题呢?你会创建一个包装类或虚拟类,或者你只是将COM对象保留在DI容器之外并简单地通过它实例化它们CreateComObject?
我已经下载了最新版本的 Delphi Spring 框架。按照自述文件中的指示,我运行 Build.exe 并选择了两个版本的 Delphi(XE5 和 Seattle)。在 Delphi 安装中,我看不到软件包已安装,也看不到我的库搜索路径已修改。我缺少什么或者我还必须做些什么才能安装和使用它?
在此先感谢您的帮助。
在Chris的博客上:http://delphihaven.wordpress.com/2011/07/14/weird-in-more-ways-than-one/
我找到了以下代码
type
TLinkVisitor<T> = reference to procedure(const Item: T);
TDoubleLinked<T> = record
Prev: ^TDoubleLinked<T>;
Next: ^TDoubleLinked<T>;
Value: T;
class function Create(const aValue: T): Pointer; static;
function Add(const aValue: T): Pointer;
procedure Delete;
procedure DeleteAll;
function First: Pointer;
function Last: Pointer;
procedure ForEach(const Proc: TLinkVisitor<T>);
end;
Run Code Online (Sandbox Code Playgroud)
"引用"关键字解决了哪些问题无法通过正常的程序类型完成?
我目前正在尝试找到最好的(*)方式让两个线程交替运行并让它们互相等待.
(*)具有低CPU成本的快速的最佳组合
到目前为止,我找到了三种方法,我将它放在一些演示应用程序中,以显示我发现的问题.
使用遵循经典等待/脉冲模式的TMonitor由于所有锁定而执行得不是很好(根据SamplingProfiler在这些函数中大部分时间都会消耗).我尝试使用Windows事件(SyncObjs.TEvent),但它执行类似(即坏).
使用调用TThread.Yield的等待循环表现最佳,但显然会像疯狂一样烧掉CPU周期.如果切换发生得非常快,那无关紧要,但是当线程实际等待时会受到伤害(你可以在演示中看到).
使用TSpinWait表现很好(如果不是这三个中最好的),但只有在切换发生得非常快的情况下.由于TSpinWait的工作方式,切换性能越差,性能越差.
由于多线程不是我的优势之一,我想知道是否有这些方法的某种组合或一些完全不同的方法来在两种情况下实现良好的性能(快速和慢速切换).
program PingPongThreads;
{$APPTYPE CONSOLE}
{$R *.res}
uses
Classes,
Diagnostics,
SyncObjs,
SysUtils;
type
TPingPongThread = class(TThread)
private
fCount: Integer;
protected
procedure Execute; override;
procedure Pong; virtual;
public
procedure Ping; virtual;
property Count: Integer read fCount;
end;
TPingPongThreadClass = class of TPingPongThread;
TMonitorThread = class(TPingPongThread)
protected
procedure Pong; override;
procedure TerminatedSet; override;
public
procedure Ping; override;
end;
TYieldThread = class(TPingPongThread)
private
fState: Integer;
protected
procedure Pong; override;
public
procedure Ping; override;
end;
TSpinWaitThread = class(TPingPongThread) …Run Code Online (Sandbox Code Playgroud) 我有以下示例应用程序,显示问题:
program FalseMemLeak;
uses
ShareMem;
var
o: TObject;
begin
o := TObject.Create; // "good" leak
RegisterExpectedMemoryLeak(o);
TInterfacedObject.Create; // bad leak
end.
Run Code Online (Sandbox Code Playgroud)
我现在使用BorlndMM.dll替换和FastMMFullDebug.dll,我得到以下报告:
---------------------------
FalseMemLeak.exe: Memory Leak Detected
---------------------------
This application has leaked memory. The small block leaks are:
5 - 12 bytes: TObject x 1
13 - 20 bytes: TInterfacedObject x 1
---------------------------
OK
---------------------------
Run Code Online (Sandbox Code Playgroud)
当我删除"坏"内存泄漏一切都很好,没有显示报告.但是一旦出现意外的内存泄漏,它也会列出已注册的泄漏.
最初我在寻找这些Indy内存泄漏时发现了这一点,并发现它们已经注册但仍然报告了那些真正的内存泄漏.
当我使用内置时ReportMemoryLeaksOnShutdown := True,它只报告泄漏TInterfacedObject.
那么有什么方法可以在完全调试模式下使用FastMM时过滤掉已注册的内存泄漏?
为了清楚起见:这是FastMM zip附带的BorlndMM.dll,它声明这是开箱即用的替代品,它使用FastMM4并加载FastMM_FullDebugMode.dll.因此,对内存管理器的所有调用都由FastMM4处理.但不知何故,似乎忽略了过滤掉已注册的泄漏(在替换的BorlndMM.dll中注册了FastMM - 在调试该DLL时可以看到).是的,使用FastMM4.pas时未报告已注册的泄漏,但更改内容并未引起争议.
我有一个复合组件,由a TEdit和a TButton(是的,我知道TButtonedEdit)继承而来TCustomControl.编辑和按钮在其构造函数中创建并放置在自身上.
在设计时,选择框没有正确绘制 - 我的猜测是编辑和按钮隐藏它,因为它是为自定义控件绘制的,然后由它们透支.
这里比较:
我也看到过其他第三方组件(比如TcxGrid也只绘制选择指标的外部)
问题:我该如何改变?
最简单的复制案例:
unit SearchEdit;
interface
uses
Classes, Controls, StdCtrls;
type
TSearchEdit = class(TCustomControl)
private
fEdit: TEdit;
public
constructor Create(AOwner: TComponent); override;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Custom', [TSearchEdit]);
end;
{ TSearchEdit }
constructor TSearchEdit.Create(AOwner: TComponent);
begin
inherited;
fEdit := TEdit.Create(Self);
fEdit.Parent := Self;
fEdit.Align := alClient;
end;
end.
Run Code Online (Sandbox Code Playgroud) 我正在一个旧的旧项目中工作,该项目有几个类,在其中published始终声明该节而内部没有任何内容,即:
TMyClass = class
public
procedure DoSomething();
published
end;
Run Code Online (Sandbox Code Playgroud)
编译时,我收到以下警告消息:
[DCC警告] uMyUnit.pas(141):W1055发布导致RTTI($ M +)添加到类型'TMyClass'
我不知道前任开发人员是否published出于某些正当理由声明了这些部分。删除空白published部分始终是安全的,还是会导致应用程序行为发生某些变化?
我有一个 Delphi Firemonkey EXIF 实现,我在例程中使用它来加载图像文件。我试图确定图像是否已旋转,以便我可以在显示图像之前纠正图像的方向。该例程部分调用执行 BSWAP 的汇编代码来确定图像文件中标头信息的位置。这是代码的一部分:
type
TMarker = packed record
Marker : Word; //Section marker
Len : Word; //Length Section
Indefin : Array [0..4] of Char; //Indefiner - "Exif" 00, "JFIF" 00 and ets
Pad : Char; //0x00
end;
TIFDHeader = packed record
pad : Byte; //00h
ByteOrder : Word; //II (4D4D) or MM
i42 : Word; //2A00 (magic number from the 'Hitchhikers Guide'
Offset : Cardinal; //0th offset IFD
Count : Word; // number of IFD entries …Run Code Online (Sandbox Code Playgroud) delphi ×10
generics ×2
spring4d ×2
assembly ×1
collections ×1
com ×1
controls ×1
delphi-xe7 ×1
fastmm ×1
memory-leaks ×1
tdictionary ×1
vcl ×1
x86-64 ×1