这个例子当然是简化了,但基本上我有一个主表单触发另一个表单(frmSettings):
function Execute(var aSettings: TSettings):Boolean
TSettings
是我在主窗体中创建的用于跟踪设置的对象。
在这个新打开的表单 (frmSettings) 中,我获取一个继承自 TObjectList
的 TMyObjectList
。
它被填充了 TMyObj
。
然后,我使用 TMyObjectList 中的值填充了一个 TListBox
。
代码如下:
...
FMyObjectList : TMyObjectList;
property MyObjectList: TMyObjectList read getMyObjectList;
...
function TfrmSettings.getMyObjectList: TMyObjectList ;
begin
If not Assigned(FMyObjectList) then FMyObjectList := TMyObjectList.Create(True)
Result := FMyObjectList;
end;
function TfrmSettings.Execute(var aSettings: TSettings): Boolean;
begin
//Fill myObjectList
FetchObjs(myObjectList);
//Show list to user
FillList(ListBox1, myObjectList);
//Show form
ShowModal;
Result := self.ModalResult = mrOk;
if Result then
begin
// Save the selected object, but how??
// Store only pointer? Lost if list is destroyed.. no good
//Settings.selectedObj := myObjectList.Items[ListBox1.ItemIndex];
// Or store a new object? Have to check if exist already?
If not Assigned(Settings.selectedObj) then Settings.selectedObj := TMyObj.Create;
Settings.selectedObj.Assign(myObjectList.Items[ListBox1.ItemIndex];);
end;
end;
procedure TfrmSettings.FillList(listBox: TListBox; myObjectList: TMyObjectList);
var
i: Integer;
begin
listBox.Clear;
With myObjectList do
begin
for i := 0 to Count - 1 do
begin
//list names to user
listBox.Items.Add(Items[i].Name);
end;
end;
end;
procedure TfrmSettings.FormDestroy(Sender: TObject);
begin
FreeAndNil(FMyObjectList);
end;
仅存储指针似乎不是一个好主意,因为再次触发设置表单会重新创建列表,即使用户点击“取消”,原始对象也将丢失。
因此,存储副本似乎更好,使用assign获取所有正确的属性。并首先检查是否已经拥有一个对象。
If not Assigned(Settings.selectedObj) then Settings.selectedObj := TMyObj.Create;
Settings.selectedObj.Assign(myObjectList.Items[ListBox1.ItemIndex];);
我应该将这两行代码移动到一个方法中,例如:Settings.AssignSelectedObj(aMyObj:TMyObj)
这样做是否正确,或者我实现的方式有误?还需要更少或更多的东西吗?
我需要一些指南,以便我感到更加安全,不会开启内存泄漏和其他问题。
除此之外,对代码进行一些审查,真正的问题是:在设置类中存储我的SelectedObject的方式是否正确?