我在将 TObject
值添加到 Delphi 10.0 Seattle 中的 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;
最佳答案
问题是在 iOS 和 Android(很快还有 Linux)上,TObject
使用 Automatic Reference Counting用于生命周期管理,因此您不能将整数值类型转换为 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];
这可移植到所有平台,无需使用 IFDEF
或担心 ARC。
关于android - Android 上的 Delphi FireMonkey TListBox AddObject 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42703494/