#delphi
Не могу найти решение для устранении утечки. type TMyObj = class Caption: string; Description: string; Params:string; ParamsLst: TStringList; public constructor Create(const aPath: string; const aParams: TStrings); overload; destructor Destroy(); override; end; TDataList = class(TObjectList) public constructor Create; // function LoadFromINI(IniFile: TMemIniFile): boolean; function Remove(Obj: TMyObj): Integer; end; var TObjData: TDataList; implementation constructor TMyObj.Create(const aPath: string; const aParams: TStrings); begin Caption := aParams.Values['Caption']; Description := aParams.Values['Description']; Params := aParams.Values['Params']; if aParams.Values['Params'] <> '' then begin ParamsLst := TStringList.Create; try ExtractStrings([';', ','], [' '], PChar(Params), ParamsLst); except ParamsLst := nil; end; end; end; destructor TMyObj.Destroy; begin ParamsLst.Free; inherited; end; constructor TDataList.Create; begin inherited Create; OwnsObjects := True; end; function TDataList.Remove(Obj: TMyObj): Integer; begin Result := inherited Remove(Obj); end; initialization TObjData := TDataList.Create; finalization TObjData.Free; заполнение TObjData, так TObjData.Add(TMyObj.Create(sVal, SecParams));
Ответы
Ответ 1
Что касается исключения - точное место создания объекта, который не уничтожился может показать FastMM или EurekaLog. Приведенный код рабочий и в большинстве случаев все правильно освобождается. (Нюансы описал ниже.) Скорее всего вы создается TreeList и его не уничтожаете (либо ждете что его уничтожит родительский объект, а он не назначен). Остальные нюансы: Может я что то упустил, но я не вижу откуда берутся данные для заполнения SecParams. Если вы до момента добавления создали SecParams - его нужно уничтожить. Иначе будет утечка. TObjData.Add(TMyObj.Create(sVal, SecParams)); Второй участок try..except. При возникновении исключения - объект все же не уничтожится. ParamsLst := TStringList.Create; try ExtractStrings([';', ','], [' '], PChar(Params), ParamsLst); except ParamsLst := nil; // end; Хотя тоже не ясно, ну не обработались параметры, значит они в неправильном формате - объект создастся, но с пустым параметром ParamsLst. И если к нему обратится без проверки - будет Access Violation. TObjData - есть общие правила когда с буквы T начинаются описания типов. F - для внутренних полей класса. var TObjData: TDataList; Для полей класса TMyObj нужно явно указать идентификатор видимости (private, public), а еще лучше перенести их в секцию private и дать доступ к полям с помощью свойств. Например: type TMyObj = class FCaption: string; public ... property Caption: string read FCaption; end; TMyObj - название класса должно описывать объект. (Например: TPerson)Ответ 2
В коде нет ни одного момента заполнения переменной со странным именем TObjData. Но могу предположить, что OwnsObjects не правильно срабатывает. В финализации перед разрушением объекта TObjData лучше сделать цикл проверки вложенных в него объектов и выяснения по какой причине они не освобождаются до финализации.Ответ 3
Код с учетом замечаний и предложений...... type TData = class private FCaption: string; FDescription: string; FParams: string; FParamsLst: TStringList; //.... public constructor Create(const aPath: string; const aParams: TStrings); destructor Destroy(); override; property Caption: string read FCaption; property Description: string read FDescription; property Params: string read FParams; property ParamsLst: TStringList read FParamsLst; //... end; TDataList = class(TObjectList) private //... public constructor Create; destructor Destroy(); override; property //... end; var DataList: TDataList; implementation { TData } constructor TData.Create(const sPath: string; const sData: TStrings); begin Caption := aParams.Values['..']; Description := aParams.Values['..']; Params := aParams.Values['..']; if aParams.Values['..'] <> '' then begin ParamsLst := TStringList.Create; try ExtractStrings([','], [' '], PChar(Params), ParamsLst); except on E: Exception do ShowMessage(E.ClassName + ': ' + E.Message); end; end; end; destructor TData.Destroy; begin inherited; end; { end TData } { DataList } constructor TDataList.Create; begin inherited Create; OwnsObjects := True; end; destructor TDataList.Destroy; begin inherited; end; { end DataList } Решение, проблемы ...... procedure TMain.FormDestroy(Sender: TObject); var I: Integer; begin // Удаление списков в объекте for i := 0 to DataList.Count - 1 do begin with DataList.Items[i] do begin ParamsLst.Free; end; end; // При удалении списка оставшиеся в нём объекты будут удалены. FreeAndNil(DataList); end;
Комментариев нет:
Отправить комментарий