#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;
Комментариев нет:
Отправить комментарий