首页 > 解决方案 > INI 文件在退出后不会保留值 - RAD Studio 10.4.2

问题描述

这个简单的代码工作了很长时间。但现在它已经停止工作了。

应用程序启动后,它会加载最后一个位置Combobox last_city。如果我更改索引Comboboxlast_city则更改。如果我读取值一切正常,直到我退出应用程序。但是在我退出应用程序并再次运行应用程序后,值就消失了。

知道为什么这停止工作了吗?谷歌的一些变化?API 28(安卓 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;

标签: androiddelphi

解决方案


查看您的代码,我在任何地方都看不到您app_ini.Free

为什么这很重要?当您调用app_ini.FreeTINiFile 类的析构函数时,将执行该类。在释放其内存析构函数之前,还要确保对 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 摧毁的,现在可能不再被摧毁了。


推荐阅读