后台:Windows 64位应用程序,Firemonkey,Delphi XE7
我有大约10个TStringGrid组件,并且当单元格中的值不是“正常”时,所有这些组件都使用相同的onDrawColumnCell来更改单元格颜色。
我正在使用以下代码,但如果屏幕上显示红色单元格,则会发生严重的内存泄漏。(如果我将页面滚动到没有显示红色单元格的位置,则没有内存泄漏)。
procedure TForm.grid_DrawColumnCell(Sender: TObject;
const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF;
const Row: integer; const Value: TValue; const State: TGridDrawStates);
var
RowColor: TBrush;
begin
RowColor := TBrush.Create(TBrushKind.Solid, TAlphacolors.Alpha);
if (Value <> 'Normal') then
RowColor.Color := TAlphacolors.Red
else
RowColor.Color := TAlphacolors.Null;
Canvas.FillRect(Bounds, 0, 0, [], 1, RowColor);
{ perform default drawing }
TGrid(Sender).DefaultDrawColumnCell(Canvas, Column, Bounds, Row,
Value, State);
end;
有谁知道如何解决内存泄漏问题?
由于
答案 0 :(得分:1)
您正在泄露RowColor
。与您管理的任何资源一样,您需要销毁它。使用标准模式:
Obj := TMyClass.Create;
try
// do stuff with Obj
finally
Obj.Free;
end;
显然,在您的代码中,您将Obj
替换为RowColor
。我用通用名称编写了代码,试图说明这是一个模式。只要有一个必须管理其生命周期的对象,并且其生命周期不超出创建它的函数,就应用此模式。
如果您使用的是其中一个移动编译器,那么您的代码就可以了。移动编译器使用ARC,自动引用计数来管理类实例的生命周期。但桌面编译器的情况并非如此。
如果您安装了FastMM的完整版本,您可以使用它来为分配导致任何泄漏的堆栈跟踪。这通常足以让你找出泄漏的原因。
FWIW我更喜欢这样编码,只在需要时创建画笔:
var
RowColor: TBrush;
begin
if Value <> 'Normal' then
begin
RowColor := TBrush.Create(TBrushKind.Solid, TAlphacolors.Red);
try
Canvas.FillRect(Bounds, 0, 0, [], 1, RowColor);
finally
RowColor.Free;
end;
end;
TGrid(Sender).DefaultDrawColumnCell(Canvas, Column, Bounds, Row,
Value, State);
end;