小编jpf*_*ius的帖子

Firemonkey和大量数据

我刚看了一下Firemonkey的网格实现,结果发现它是一个非常简单的实现(只有1800行,对于网格实现来说似乎并不多).它几乎没有自定义绘画,而是聚合了许多其他控件 - 这似乎是Firemonkey的做事方式.

例如,每列保留一组控件 - 每个单元一个.对于具有1,000,000行的普通文本列,网格将在内存中保留1,000,000个编辑控件 - 这对我来说似乎有点疯狂.(编辑:现在不太确定,如果这个假设是正确的.它似乎考虑了细胞的可见性,这可能意味着它确实提供了类似虚拟模式的东西,但我不太确定......)

我的问题:毫无疑问,Firemonkey的这种组件聚合设计看起来简单而优雅,但是它真的可以很好地扩展到必须在网格中显示的数据量吗?我无法想象它在大量行中表现良好.什么是Firemonkey处理大量数据的方式?

感谢您的任何意见.

delphi delphi-xe2 firemonkey

12
推荐指数
1
解决办法
5173
查看次数

匿名方法的范围

匿名方法的一个好处是我可以使用调用上下文中的本地变量.有什么理由说这不适用于输出参数和功能结果吗?

function ReturnTwoStrings (out Str1 : String) : String;
begin
  ExecuteProcedure (procedure
                    begin
                      Str1 := 'First String';
                      Result := 'Second String';
                    end);
end;
Run Code Online (Sandbox Code Playgroud)

当然是非常人为的例子,但我遇到了一些有用的情况.

当我尝试编译它时,编译器抱怨他"无法捕获符号".此外,当我尝试这样做时,我收到了一个内部错误.

编辑我刚刚意识到它适用于普通参数

... (List : TList)
Run Code Online (Sandbox Code Playgroud)

这不像其他案件那样有问题吗?谁保证只要执行匿名方法,引用仍指向活动对象?

delphi scope anonymous-methods delphi-2009

10
推荐指数
2
解决办法
4155
查看次数

为什么ReadDirectoryChangesW会忽略事件?

我使用ReadDirectoryChangesW来监视指定的目录,并在检测到更改时更新索引结构.我使用以下代码(粗略)

var
  InfoPointer : PFileNotifyInformation;
  NextOffset : DWORD;
...
while (not Terminated) do begin
  if ReadDirectoryChangesW (FDirHandle, FBuffer, FBufferLength, True,
                            FFilter, @BytesRead, @FOverlap, nil) then
    begin
    WaitResult := WaitForMultipleObjects (2, @FEventArray, False, INFINITE);
    if (WaitResult = waitFileChange) then
      begin 
      InfoPointer := FBuffer;
      repeat
        NextOffset := InfoPointer.NextEntryOffset;
        ...
        PByte (InfoPointer) := PByte (InfoPointer) + NextOffset;
      until NextOffset = 0;
      end;
    end;
end;  
Run Code Online (Sandbox Code Playgroud)

过滤器是

FFilter :=  FILE_NOTIFY_CHANGE_FILE_NAME or
            FILE_NOTIFY_CHANGE_DIR_NAME or
            FILE_NOTIFY_CHANGE_SIZE or
            FILE_NOTIFY_CHANGE_LAST_WRITE;
Run Code Online (Sandbox Code Playgroud)

和目录句柄是这样获得的:

FDirHandle := CreateFile (PChar (FDirectoryWatch.WatchedDirectory),
                          FILE_LIST_DIRECTORY or GENERIC_READ, …
Run Code Online (Sandbox Code Playgroud)

windows filesystems delphi readdirectorychangesw delphi-2009

10
推荐指数
2
解决办法
8357
查看次数

序列化Delphi应用程序配置的最佳方法是什么?

我会自己回答这个问题,但如果你比我快,或者你不喜欢我的解决方案,请随时提供你的答案.我想出了这个想法,并希望对此有一些看法.

目标:一个可读的配置类(如INI文件),但无需编写(并在添加新配置项后进行调整)加载和保存方法.

我想创建一个类

TMyConfiguration = class (TConfiguration)
  ...
  property ShowFlags : Boolean read FShowFlags write FShowFlags;
  property NumFlags : Integer read FNumFlags write FNumFlags;
end;
Run Code Online (Sandbox Code Playgroud)

调用TMyConfiguration.Save(继承自TConfiguration)应该创建一个类似的文件

[Options]
ShowFlags=1
NumFlags=42
Run Code Online (Sandbox Code Playgroud)

问题:最好的方法是什么?

delphi configuration-files rtti

10
推荐指数
2
解决办法
3810
查看次数

我应该使用无符号整数来计算成员吗?

我应该为计数类成员使用无符号整数吗?

回答

例如,假设一个类

TList <T> = class
private
  FCount : Cardinal;
public
  property Count : Cardinal read FCount;
end;
Run Code Online (Sandbox Code Playgroud)

这确实有道理,不是吗?列表中存储的项目数不能为负数,那么为什么不使用无符号整数类型呢?我认为总是使用最不通用的(最特殊的)类型是一个很好的原则.

现在,迭代列表如下所示:

for I := 0 to List.Count - 1 do
  Writeln (List [I]);
Run Code Online (Sandbox Code Playgroud)

当列表中存储的项目数为零时,编译器会尝试进行评估

List.Count - 1
Run Code Online (Sandbox Code Playgroud)

这导致一个很好的整数溢出(确切地说是下溢).结合调试器没有显示发生异常的适当位置的事实,这对我来说很难找到.

让我补充一点,如果你关闭溢出检查,结果错误将更难跟踪,因为那时你经常会访问不属于你的内存 - 这会导致未定义的行为.

从现在开始,我将为所有计数成员使用普通整数来避免这种情况.

如果这完全是胡说八道,请指出给我:)

(我只花了一个小时跟踪代码中的整数溢出,所以我决定分享一下 - 当然大多数人都会知道,但也许我可以节省一些时间.)

delphi integer-overflow

9
推荐指数
4
解决办法
1576
查看次数

Delphi中的命名空间

使用像MyLib.MyUtils.pas这样的长单元文件名是否有任何实际好处, 或者它只是一种单元名称前缀?

delphi namespaces

9
推荐指数
1
解决办法
7066
查看次数

快速复制TList <T>?

有没有快速的方法来复制通用TList?

Copy.Capacity := List.Count;
for Item in List do
  Copy.Add (Item);
Run Code Online (Sandbox Code Playgroud)

非常慢 似乎没有办法使用,CopyMemory因为我无法获得内部数组的内存地址(从信息隐藏的角度来看很明显).我错过了类似的东西

List.Copy (Copy);
Run Code Online (Sandbox Code Playgroud)

它使用内部表示的知识来提高性能.可以吗?

delphi collections delphi-xe

9
推荐指数
1
解决办法
2775
查看次数

对象的引用计数

在我的代码中,我使用了一个小型数据存储类,它在不同的地方创建.为了避免内存泄漏并简化操作,我想使用引用计数,所以我做到了

type TFileInfo = class (TInterfacedObject, IInterface)
Run Code Online (Sandbox Code Playgroud)

并删除了我对TFileInfo.Free的所有手动调用.不幸的是Delphi报告了很多内存泄漏.搜索SO我发现以下问题解释了为什么这不起作用:

为什么不收集TInterfacedObject垃圾的后代?

这里有一个解决方法,但它需要我(至少如果我做对了)编写一个自定义接口IFileInfo并为它提供了许多getter和setter,我想避免它.

编辑我应该补充一点,我将创建的FileInfo对象插入到两种不同类型的哈希表中:一个来自TBucketList,另一个是来自Codegear论坛的哈希映射实现.在内部它们都是用户指针,因此情况就像在另一个问题中一样.

还有其他可能使Delphi中的对象使用引用计数吗?

delphi interface reference-counting tinterfacedobject

8
推荐指数
2
解决办法
5530
查看次数

德尔福和i18n

Delphi是否以任何方式支持国际化?

我已经看到我可以为项目添加不同的语言,但这似乎创建了dfm文件的多个实例.我是否正确,因此语言无法在运行时更改?

你如何处理国际化(如果你这样做)?有没有最好的做法?

delphi delphi-2009 internationalization

8
推荐指数
2
解决办法
2176
查看次数

D2009中的泛型是否可用于大型项目?

我非常沮丧.我正在使用Delphi 2009,并且很高兴在这个版本的Delphi中包含泛型.一切都在一开始就很好用,但是现在我在整个地方使用泛型我遇到了问题 - 大多数时候是一些内部错误,我甚至都看不到它们究竟在哪里造成的.我尝试多次重构代码以避免泛型问题,但总是遇到新的问题.

现在我决定完全删除泛型并使用一些动态强制转换来专门化我的类.不是很激动,但我没有看到另一种选择.我不能花一天时间追踪Delphi的内部编译错误......

是否有人在大型项目中使用泛型而没有遇到这样的问题?也许是我的错吗?或者只是不可能在复杂的项目中使用它们?

我希望D2010修复所有这些东西.

delphi generics delphi-2009

8
推荐指数
2
解决办法
565
查看次数