Delphi-使用动态数组管理TList



我有一个用于绘制样条曲线的组件,它是TPoint数组中样条曲线过程的参数。现在,我想创建一个动态的TPoint数组,将其保存在TList中,并在调用后绘制样条曲线。

p.S.德尔福XE5

示例:

var
l: TList;
procedure CreateSpline;
var i, x: byte;
p: TPoint;
a: array of TPoint;
begin
l := TList.Create;
for x := 0 to 9 do  // create 10 splines
begin
SetLength(a, Random(10) + 5);   Each spline has 5<n<15 points
for i := 0 to High(a) do
begin
p.X := Random(200) - 100;   // X coord
p.Y := Random(200) - 100;   // Y coord
a[i] := p;                  // add point to array
end;
l.Add(a);                       // add array to TList
end;
end;
procedure DrawSpline;
var i: byte;
a: array of TPoint;
begin
for i := 0 to 9 do
begin
a := l[i];
xyPlot.Spline(a);  // Draw the spline (xyPlot is the graphic component)
end;
end;

不工作-(

非泛型System.Classes.TList只是一个原始指针的容器,它不知道它包含什么。动态数组是引用计数的,TList不会为您管理引用计数,因此您必须手动执行此操作,以确保数组在列表中时引用计数递增,例如:

ar
l: TList;
procedure CreateSpline;
var
i, x: byte;
p: TPoint;
a: TArray<TPoint>;
aptr: Pointer;
begin
l := TList.Create;
for x := 0 to 9 do  // create 10 splines
begin
SetLength(a, Random(10) + 5);   // Each spline has 5<n<15 points
for i := 0 to High(a) do
begin
p.X := Random(200) - 100;     // X coord
p.Y := Random(200) - 100;     // Y coord
a[i] := p;                    // add point to array
end;
TArray<TPoint>(aptr) := a;
try
l.Add(aptr);                  // add array to TList
except
TArray<TPoint>(aptr) := nil;
raise;
end;
a := nil;
end;
end;
{ alternatively:
procedure CreateSpline;
var
i, x: byte;
p: TPoint;
a: TArray<TPoint>;
begin
l := TList.Create;
for x := 0 to 9 do  // create 10 splines
begin
SetLength(a, Random(10) + 5);   // Each spline has 5<n<15 points
for i := 0 to High(a) do
begin
p.X := Random(200) - 100;     // X coord
p.Y := Random(200) - 100;     // Y coord
a[i] := p;                    // add point to array
end;
l.Add(Pointer(a));              // add array to TList
Pointer(a) := nil;
end;
end;
}
procedure DrawSpline;
var
i: byte;
a: TArray<TPoint>;
begin
for i := 0 to 9 do
begin
a := TArray<TPoint>(l[i]);
xyPlot.Spline(a);  // Draw the spline (xyPlot is the graphic component)
end;
end;
...
// later, you need to decrement the refcounts before freeing/clearing the TList...
var
i: byte;
aptr: Pointer;
begin
for i := 0 to 9 do
begin
aptr := l[i];
TArray<TPoint>(aptr) = nil;
end;
l.Free;
end;

更好的解决方案是使用泛型System.Generics.Collections.TList<T>,其中TTArray<TPoint>。然后将为您正确管理参考计数,例如:

ar
l: TList<TArray<TPoint>>;
procedure CreateSpline;
var
i, x: byte;
p: TPoint;
a: TArray<TPoint>;
begin
l := TList<TArray<TPoint>>.Create;
for x := 0 to 9 do  // create 10 splines
begin
SetLength(a, Random(10) + 5);   // Each spline has 5<n<15 points
for i := 0 to High(a) do
begin
p.X := Random(200) - 100;     // X coord
p.Y := Random(200) - 100;     // Y coord
a[i] := p;                    // add point to array
end;
l.Add(a);                       // add array to TList
end;
end;
procedure DrawSpline;
var
i: byte;
a: TArray<TPoint>;
begin
for i := 0 to 9 do
begin
a := l[i];
xyPlot.Spline(a);  // Draw the spline (xyPlot is the graphic component)
end;
end;
...
l.Free;

最新更新