繁体   English   中英

INI 文件在退出后不会保留值 - RAD Studio 10.4.2

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM