问题描述
在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 IFDEF
s or worrying about ARC.
这篇关于Android上的Delphi FireMonkey TListBox AddObject异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!