[英]INI File wont keep values after exit - RAD Studio 10.4.2
这个简单的代码已经运行了很长时间。 但现在它已经停止工作了。
应用程序启动后,它会加载Combobox
last_city
最后一个位置。 如果我更改Combobox
索引,则last_city
会更改。 如果我读取值一切正常,直到我退出应用程序。 但是在我退出应用程序并再次运行应用程序后,值就消失了。
知道为什么这停止工作了吗? 来自谷歌的一些变化? Api 28 (Android 9)。 RAD 工作室 10.4.2
procedure TForm1.FormCreate(Sender: TObject);
var data: string;
begin
app_ini := TIniFile.Create(TPath.GetDocumentsPath + PathDelim + 'app.ini', TEncoding.ANSI);
data := app_ini.ReadString('nastaveni', 'last_city', '');
if data <> '' then // load last city
begin
cb_mesta.SetFocus;
cb_mesta.ItemIndex := StrToInt(data);
cb_mesta.OnChange(Self);
cb_mezi.ItemIndex := StrToInt(app_ini.ReadString('nastaveni', 'last_adr', ''));
cb_mezi.OnChange(Self);
ch_last.IsChecked := True;
end;
end;
procedure TForm1.ch_lastChange(Sender: TObject); // when change city i safe change to ini file
begin
if ch_last.IsChecked then
begin
app_ini.WriteString('nastaveni', 'last_city', IntToStr(cb_mesta.ItemIndex));
app_ini.WriteString('nastaveni', 'last_adr', IntToStr(cb_mezi.ItemIndex));
end
else
begin
app_ini.WriteString('nastaveni', 'last_city', '');
app_ini.WriteString('nastaveni', 'last_adr', '');
end;
end;
查看您的代码,我没有看到您在任何地方调用app_ini.Free
。
为什么这很重要? 当您调用app_ini.Free
,会执行 TIniFile 类的析构函数。 在释放其内存析构函数之前,还要确保对 TIniFile 对象所做的所有更改在其销毁之前写入 INI 文件。
但是为什么这些更改在发生时不立即写入 INI 文件呢? 答案是性能。
您会看到 INI 文件是基于文本的文件。 并且当您向基于文本的文件添加新文本时,或者如果您将现有文本的一部分替换为另一个长度不同的文本,则该文本之后的所有文本都需要移动。 这意味着您需要读取在您更改到内存的点之后的所有文本进行更改,然后将您已读入内存的所有文本写回文件。 这会产生很多额外的开销。
为了避免这种额外的开销,TIniFile 将其内容存储在内存中,并且仅在调用TIniFile.UpdateFile
时将更改写入文件。
为什么这在过去对您有用而现在不再适用?
当 Delphi XE4 首次引入对移动平台的支持时,这些平台的内存管理器基于 ARC(自动引用计数)机制。
在基于 ARC 的内存管理中,内存管理器使用特定对象的引用计数来确定是否需要销毁它。 每次引用特定对象时引用计数都会增加,每次清除/删除对特定对象的引用时都会减少引用计数。 当引用计数达到零时,对象就会被销毁。
因此,在从 Delphi XE4 到包括移动平台上的 Delphi 10.3 的 Delphi 版本中,作为开发人员的您无需过多关注释放特定对象,因为这是由内存管理器自动完成的。
但是 Delphi 10.4 删除了 ARC 内存管理(仍然保留用于接口和字符串),目的是将内存管理与从未使用过基于 ARC 的内存管理(接口和字符串除外)的 Windows 平台统一。
自从您最近迁移到 Delphi 10.4 以来,用于将数据存储到 INI 文件的代码过去可以正常工作,因为它依赖于基于 ARC 的内存管理,但现在停止正常工作。
PS:我强烈建议您检查整个代码,因为如果在编写时考虑了基于 ARC 的内存管理,则缺少 ARC 内存管理可能也会影响代码的其他部分,因为该代码现在可能会作为对象产生内存泄漏依赖于被ARC摧毁的现在可能不再被摧毁。
原因是新的 Delphi,而不是正确编写的应用程序。
第一种方式( app_ini.UpdateFile;
): app_ini.UpdateFile;
在写入新值之后,或至少在退出应用程序之前
第二种方式(SilverWarior): app_ini.Free;
进入您的 Form1 OnDestroy 事件。
但我认为最好是他们两个来确定保存的值。
谢谢大家的帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.