1

我在为Delphi 10.0 SeattleTObject的 FireMonkey 添加值时遇到问题。TListBox

Integer将变量转换为TObject指针时会引发异常。

我尝试了演员阵容TFmxObject,但没有成功。在 Windows 上,演员阵容就像一个魅力,但在 Android 上却引发了例外。

这是我的代码:

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;
4

1 回答 1

5

问题在于,在 iOS 和 Android(以及很快的 Linux)上,TObject使用自动引用计数进行生命周期管理,因此您不能TObject像在不使用 ARC 的 Windows 和 OSX 上那样将整数值类型转换为指针。在 ARC 系统上,TObject指针必须指向真实对象,因为编译器将对它们执行引用计数语义。这就是为什么你得到一个例外。

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

{$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在需要时将项目的索引用作该列表的索引,例如:

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];

这可移植到所有平台,无需使用IFDEFs 或担心 ARC。

于 2017-03-09T20:04:09.747 回答