本文介绍了Android上的Delphi FireMonkey TListBox AddObject异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Delphi 10.0 Seattle的FireMonkey TListBox中添加TObject值时遇到问题.

I'm having a problem adding a TObject value to a FireMonkey TListBox in Delphi 10.0 Seattle.

Integer变量强制转换为TObject指针时,会引发一种误解.

An exeception is raised when casting an Integer variable to a TObject pointer.

我尝试将演员表转换为TFmxObject,但没有成功.在Windows上,强制转换的工作方式像一个超级按钮,但在Android上,它引发了异常.

I tried the cast to TFmxObject with no success. On Windows, the cast works like a charm, but on Android it raises the exception.

这是我的代码:

var
  jValue:TJSONValue;
  i,total,id: integer;
  date: string;
begin
  while (i < total) do
  begin
    date := converteDate(jValue.GetValue('date' + IntToStr(i), ''));
    id := StrToInt(jValue.GetValue('id' + IntToStr(i), ''));
    ListBox1.Items.AddObject(date, TObject(id));
    i := i + 1;
  end;
end;

推荐答案

问题是,在iOS和Android(以及不久的Linux)上,TObject使用用于自动管理的自动引用计数,因此,您不能像在Windows和OSX上那样将整数值强制转换为TObject指针.不使用ARC.在ARC系统上,TObject指针必须指向实际对象,因为编译器将对它们执行引用计数语义.这就是为什么您遇到例外.

The problem is that on iOS and Android (and soon Linux), TObject uses Automatic Reference Counting for lifetime management, and as such you cannot type-cast integer values as TObject pointers, like you can on Windows and OSX, which do not use ARC. On ARC systems, TObject pointers must point to real objects, as the compiler is going to perform reference-counting semantics on them. That is why you are getting an exception.

要执行您要尝试的操作,必须将整数值包装在ARC系统上的实对象内,例如:

To do what you are attempting, you will have to wrap the integer value inside of a real object on ARC systems, eg:

{$IFDEF AUTOREFCOUNT}
type
  TIntegerWrapper = class
  public
    Value: Integer;
    constructor Create(AValue: Integer);
  end;

constructor TIntegerWrapper.Create(AValue: Integer);
begin
  inherited Create;
  Value := AValue;
end;
{$ENDIF}

...

ListBox1.Items.AddObject(date, {$IFDEF AUTOREFCOUNT}TIntegerWrapper.Create(id){$ELSE}TObject(id){$ENDIF});

...

{$IFDEF AUTOREFCOUNT}
id := TIntegerWrapper(ListBox1.Items.Objects[index]).Value;
{$ELSE}
id := Integer(ListBox1.Items.Objects[index]);
{$ENDIF}

否则,将整数存储在单独的列表中,然后在需要时使用TListBox项的索引作为该列表的索引,例如:

Otherwise, store your integers in a separate list and then use the indexes of the TListBox items as indexes into that list when needed, eg:

uses
  .., System.Generics.Collections;

private
  IDs: TList<Integer>;

...

var
  ...
  Index: Integer;
begin
  ...
  Index := IDs.Add(id);
  try
    ListBox1.Items.Add(date);
  except
    IDs.Delete(Index);
    raise;
  end;
  ...
end;

...

Index := ListBox1.Items.IndexOf('some string');
id := IDs[Index];

这可移植到所有平台,而无需使用IFDEF或担心ARC.

This is portable to all platforms without having to use IFDEFs or worrying about ARC.

这篇关于Android上的Delphi FireMonkey TListBox AddObject异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 20:45