PStringItem = ^TStringItem;
TStringItem = record
FString: string;
FObject: TObject;
end;
PStringItemList = ^TStringItemList;
TStringItemList = array[0..MaxListSize] of TStringItem;
一个非常大的结构体数组。
TStringList = class(TStrings)
private
FList: PStringItemList;
FCount: Integer;
FCapacity: Integer;
FSorted: Boolean;
function TStringList.Get(Index: Integer): string;
begin
if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
Result := FList^[Index].FString;
end;//返回的是字符串,而不是对象。
function TStringList.GetObject(Index: Integer): TObject;
begin
if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
Result := FList^[Index].FObject;//返回的是对象
end;
function TStringList.GetCount: Integer;
begin
Result := FCount;
end;//元素个数
function TStringList.GetCapacity: Integer;
begin
Result := FCapacity;
end;//得到的最大容量
//两个事件.
procedure TStringList.Changed;
begin
if (FUpdateCount = 0) and Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TStringList.Changing;
begin
if (FUpdateCount = 0) and Assigned(FOnChanging) then
FOnChanging(Self);
end;
type
Str18 = string[18];
var
P: ^Str18;
begin
New(P);
P^ := 'Now you see it...';
Dispose(P); { Now you don't... }
end;
Use Dispose in Delphi code to free the memory which a pointer addresses. After a call to Dispose, the value of P is undefined and it is an error to reference P.
You can create dynamic variables by calling the GetMem or New procedure. Such variables are allocated on the heap and are not managed automatically. Once you create one, it is your responsibility ultimately to free the variable's memory; use FreeMem to destroy variables created by GetMem and Dispose to destroy variables created by New. Other standard routines that operate on dynamic variables include ReallocMem, AllocMem, Initialize, Finalize, StrAlloc, and StrDispose.
Long strings, wide strings, dynamic arrays, variants, and interfaces are also heap-allocated dynamic variables, but their memory is managed automatically.
procedure TStringList.Put(Index: Integer; const S: string);
begin
if Sorted then Error(@SSortedListError, 0);
if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
Changing;
FList^[Index].FString := S;
Changed;
end;
procedure TStringList.PutObject(Index: Integer; AObject: TObject);
begin
if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
Changing;
FList^[Index].FObject := AObject;
Changed;
end;
procedure TStringList.Delete(Index: Integer); //删除一个元素。
begin
if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
Changing;
Finalize(FList^[Index]);
Dec(FCount);
if Index < FCount then
System.Move(FList^[Index + 1], FList^[Index],
(FCount - Index) * SizeOf(TStringItem));
Changed;
end;
procedure TStringList.CustomSort(Compare: TStringListSortCompare);//使用快速排序功能
begin
if not Sorted and (FCount > 1) then
begin
Changing;
QuickSort(0, FCount - 1, Compare);
Changed;
end;
end;
procedure TStringList.Sort; //排序调用此函数, 该函数调用快速排序功能。
begin
CustomSort(StringListCompareStrings);
end;
function TStringList.Find(const S: string; var Index: Integer): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
L := 0;
H := FCount - 1;
while L <= H do
begin
I := (L + H) shr 1;//使用折半查找。
C := CompareStrings(FList^[I].FString, S);
if C < 0 then L := I + 1 else
begin
H := I - 1;
if C = 0 then
begin
Result := True;
if Duplicates <> dupAccept then L := I;
end;
end;
end;
Index := L;
end;
procedure TStrings.BeginUpdate; //开始更新, 根据更新次数来设置更新状态. 是更新次数加1。
begin
if FUpdateCount = 0 then SetUpdateState(True);
Inc(FUpdateCount);
end;
procedure TStringList.SetUpdateState(Updating: Boolean);// 根据状态来调用事件。
begin
if Updating then Changing else Changed; //调用Changing事件。
end;
procedure TStrings.EndUpdate; //减少更新次数。设置更新状态。
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then SetUpdateState(False); 调用Changed事件
end;