iniファイルから値を取得するプログラムを作成しているのですが、プログラム内で頻繁にiniファイルを読み書きするためprivateにIniを宣言しています。
プログラム内で「Ini := TMemIniFile.Create('C:\test.ini');」で何回かIniオブジェクトを生成して、最後にFormDestroyでまとめてIniオブジェクトを解放しようとしたのですが、下記の例で言う①のIniオブジェクトのメモリが解放されません。(②のIniオブジェクトだけ解放されます)
FormDestroyで①と②のIniオブジェクトを解放するには、
どうしたら良いのでしょうか?
1回1回Ini.Freeで解放しろと言われればそれまでですが、
Createしている箇所が多いためFormDestroyでまとめて解放出来ないかと
思った次第です。
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
Ini: TMemIniFile;
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
procedure TForm1.Button1Click(Sender: TObject);
var
strIni1: String;
strIni2: String;
begin
Ini := TMemIniFile.Create('C:\test.ini'); … ①
strIni1 := Ini.ReadString('Section', 'Key1', '');
Ini := TMemIniFile.Create('C:\test.ini'); … ②
strIni2 := Ini.ReadString('Section', 'Key2', '');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Ini.Free;
end;
1と2の二つ分の変数用意すればいいだけでしょ?
編集 削除② はいらないんじゃないですか。同じ変数に入れてるから、先に入れたほうが行方不明になるのでは。
>1回1回Ini.Freeで解放しろと言われればそれまでですが、
>Createしている箇所が多いためFormDestroyでまとめて解放出来ないかと
>思った次第です。
いちいち Free するのがこういう場合の基本だと思います。Create と同じ回数
Free しないとリークするのは当然です。
ini ファイルが一つだけなら
FormCreate で一回だけ Create して、使い回し、FormDestroy で Free するといいです。
例が悪くて言いたいことをうまく伝えれず、すみません。先例は忘れて下さい。
本当にやりたいことは、りおりおさんが言うとおりFormCreateでIniを生成してFormDestroyでIniを解放したいだけです。
しかし、②でIniファイルの内容を頻繁に更新した後、③で最新の値が取得出来なかったので、③の前に「Ini := TMemIniFile.Create('C:\test.ini');」を追加したのですが、①が解放されません。
ちなみに、上記の代わりに「Ini.UpdateFile」にしても③で最新の値が取得出来ませんでした。
>② はいらないんじゃないですか。同じ変数に入れてるから、先に入れたほうが行方不明になるのでは。
行方不明になったオブジェクトを解放することは不可能なのですか?
procedure TForm1.FormCreate(Sender: TObject);
begin
Ini := TMemIniFile.Create('C:\test.ini'); ・・・①
end;
procedure TForm1.Button1Click(Sender: TObject);
var
strIni1: String;
strIni2: String;
begin
strIni1 := Ini.ReadString('Section', 'Key1', '');
-------------------------------
Iniファイルに読み書きを行う ・・・②
-------------------------------
Ini := TMemIniFile.Create('C:\test.ini');
strIni2 := Ini.ReadString('Section', 'Key2', ''); ・・・③
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Ini.Free;
end;
-------------------------------
Iniファイルに読み書きを行う ・・・②
-------------------------------
//これが必要かね?
Ini.UpdateFile;
//Ini := TMemIniFile.Create('C:\test.ini');
strIni2 := Ini.ReadString('Section', 'Key2', ''); ・・・③
①やった後に③の記述は駄目ですよね。
って皆書いてますよね。
根本的に何をされたいのか良くわかりませんが
Iniファイルは前回起動時内容を保持させ次回起動時その内容を反映させたい
とか、ユーザー毎に何らかの初期値を保持させたい等の時に利用するもんだ
ろうと思っとります。
>プログラム内で頻繁にiniファイルを読み書きするため
何でこんな必要があるのかな?と、勝手に解釈しとります。
私なら
①アプリ起動時にIniファイルの内容を一気に何らかの変数に読み込む
②アプリ終了時にその変数値をIniファイルに書き戻します。
アプリ実行中はその変数の値を書き換え・参照するだけですみます。
そうしたら、その様な記述は無くて済みます。
みなさん返信ありがとうございます。
みなさんの言われる通り、Iniの使いまわしせずに
下記のように1回1回解放するようにします。
ご迷惑をおかけしました。
Ini := TMemIniFile.Create('C:\test.ini');
try
except
Ini.Free;
end;
>//これが必要かね?
>Ini.UpdateFile;
これでちゃんと更新がかかってくれれば問題なかったのですが、
ダメだったので、「Ini := TMemIniFile.Create('C:\test.ini');」のようにしています。
普通こうですよ。
Ini := TMemIniFile.Create('C:\test.ini');
try
finally
Ini.Free;
end;
TMemIniFileの場合、Freeの前に
Ini.UpdateFile;
を行った方がいいですね。
失礼しました。
exceptではなくfinally でした。
>TMemIniFileの場合、Freeの前に
>Ini.UpdateFile;
>を行った方がいいですね。
こういうことですか?
Ini := TMemIniFile.Create('C:\test.ini');
try
finally
Ini.UpdateFile;
Ini.Free;
end;
Iniを解放する前に更新した方が良いということですか?
どういうメリットがあるのでしょうか?
メリットというか、Ini.WriteStringとか
Write系のものを使った時
TIniFileは即時実行ですが
TMemIniFileは
UpdateFileを使わないと更新されなかった
気がしますよ。