Delphi: the right way to store objects retrieved from a TObjectList

This example is, of course, simplified, but basically I have a main form that runs another form (frmSettings) with

function Execute(var aSettings: TSettings):Boolean

TSettings - This is my own object created in the main form for tracking settings.

In this recently opened form (frmSettings), I retrieve TMyObjectLista child of TObjectList. It is full TMyObj.

Then I populate the TListBoxvalues ​​from this TMyObjectList.

the code:

...

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;

Storing only the pointer does not seem like a good idea, since it starts the settings form again, recreates the list, and the original object will be lost even if the user hits “cancel”

, , , . , .

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

Settings.AssignSelectedObj(aMyObj:TMyObj)

, ? - / ?

, , .

, , : SelectedObject ?

+3
3

?

, . . , , ? .

IMHO . , OK.

. TObjectList , . , . :

  • - , FromCreate FormDestroy. .

  • - Execute. .

+1

myObjectList GlobalObjectList . , / /. , , ini ( ). , Uses.

0

TSettings? , RTTI :

type
  TSettings = class(TPersistent)
  public
    function SaveAsText: UTF8String;
  end;

function TSettings.SaveAsText: UTF8String;
begin
var
  Stream1, Stream2: TMemoryStream;
begin
  Stream1 := TMemoryStream.Create;
  Stream2 := TMemoryStream.Create;
  try
    Stream1.WriteComponent(MyComponent);
    ObjectBinaryToText(Stream1, Stream2);
    SetString(result,PAnsiChar(Stream2.Memory),Stream2.Size);
  finally
    Stream1.Free;
    Stream2.Free;
  end;
end;

.

This is just one solution. But saving the settings as text is very convenient. We use this approach in our framework to save settings using code created using the user interface . The settings tree is created from the TPersistent instance tree.

0
source

Source: https://habr.com/ru/post/1788994/


All Articles