Delphi:存储从 TObjectList 获取的对象的正确方法

标签 delphi oop tobjectlist

这个例子当然是简化的,但基本上我有一个主窗体,它用

触发另一个窗体(frmSettings)
function Execute(var aSettings: TSettings):Boolean

TSettings 是我自己在主窗体中创建的对象,用于跟踪设置。

在这个新打开的表单 (frmSettings) 中,我获取一个 TMyObjectList,它是 TObjectList 的后代。 它充满了 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;

仅存储指针似乎不是一个好主意,因为再次触发设置表单,重新创建列表,即使用户点击“取消”,原始对象也会丢失

因此,存储副本似乎更好,使用分配来使所有属性正确。首先检查我是否已经有一个对象。

        If not Assigned(Settings.selectedObj) then Settings.selectedObj := TMyObj.Create;
        Settings.selectedObj.Assign(myObjectList.Items[ListBox1.ItemIndex];);

我应该将这两行移动到像 Settings.AssignSelectedObj(aMyObj:TMyObj) 这样的方法

这看起来正确还是我以错误的方式实现了这一点? 需要更多/更少的东西?

我需要一些指导方针,这样我就不会因为内存泄漏和其他问题而感到更安全。

除了稍微检查一下代码之外,真正的问题是:这是在设置类中存储我的 SelectedObject 的正确方法吗?

最佳答案

这是在设置中存储所选对象的正确方法吗?

可能不是。您的设置类不应以任何方式依赖于表单。如果您决定在用户​​每次打开设置时动态创建和销毁表单怎么办?在这种情况下,您的设置将包含无效的对象引用。

恕我直言,最好将对象列表与所选对象的索引一起存储在设置中。在用户单击“确定”确认后,表单应该只访问设置、填充列表框并修改所选对象索引。

您的代码中出现了内存泄漏。您创建一个 TObjectList作为局部变量,但你永远不会释放它。如果释放局部变量,列表框中的对象引用将无效。您有两个选择:

    <罢工>
  • 将对象列表存储为表单的成员变量,在 FromCreate 中创建事件处理程序并在 FormDestroy 中销毁它事件处理程序。然后,您可以安全地使用列表框中的对象引用。

  • 将对象列表存储在外部某处,并将其作为 Execute 的参数传递到表单中。方法。在这种情况下,您还可以安全地使用对象引用。

关于Delphi:存储从 TObjectList 获取的对象的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4851816/

相关文章:

java - 将枚举类与策略模式相结合进行模块化设计

delphi - 关于加入 TObjectlists

delphi - 如何通过DataSnap发送/接收TObjectList解决内存泄漏?

delphi - 基于泛型参数类型的类型推断(Delphi)

sql-server - 如何将 SQL BACKUP 命令的结果输出获取到 Delphi 程序中?

multithreading - 多线程下载字符串 delphi

delphi - Delphi中 'Result'的默认值是多少?

java - 如何使用设计模式实现最便宜的酒店查找器?

java - Java中基于ArrayList的二叉树实现

排序 TObjectList<T> 交换相等的值