[英]Delphi FireMonkey TListBox AddObject exception on Android
I'm having a problem adding a TObject
value to a FireMonkey TListBox
in Delphi 10.0 Seattle. 我在添加一个问题
TObject
值到FireMonkey TListBox
德尔福10.0西雅图。
An exeception is raised when casting an Integer
variable to a TObject
pointer. 将
Integer
变量强制转换为TObject
指针时,会引发一种理解。
I tried the cast to TFmxObject
with no success. 我尝试将演员表转换为
TFmxObject
,但没有成功。 On Windows, the cast works like a charm, but on Android it raises the exception. 在Windows上,强制转换的工作方式像一个超级按钮,但在Android上,它引发了异常。
Here is my code: 这是我的代码:
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;
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. 问题在于,在iOS和Android(以及不久的Linux)上,
TObject
使用自动引用计数进行生命周期管理,因此,您不能像在Windows和OSX上那样使用不使用ARC的类型将整数值作为类型的TObject
指针进行类型转换。 。 On ARC systems, TObject
pointers must point to real objects, as the compiler is going to perform reference-counting semantics on them. 在ARC系统上,
TObject
指针必须指向实际对象,因为编译器将对它们执行引用计数语义。 That is why you are getting an exception. 这就是为什么您要例外。
To do what you are attempting, you will have to wrap the integer value inside of a real object on ARC systems, eg: 要执行您要尝试的操作,您必须将整数值包装在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}
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: 否则,将整数存储在单独的列表中,然后在需要时使用
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];
This is portable to all platforms without having to use IFDEF
s or worrying about ARC. 它可以移植到所有平台,而不必使用
IFDEF
或担心ARC。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.