我有一个用于绘制样条曲线的组件,它是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>
,其中T
是TArray<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;