我正在使用RAD Studio XE-5创建Android应用程序,但最近偶然发现了一个令人费解的错误。 TStringList.AddObject引发以下异常:
Project Project3.apk raised exception class Segmentation fault (11).
我的代码是这个
procedure TMainForm.FormCreate(Sender: TObject);
var
list: TStrings;
begin
list := TStringList.Create;
list.AddObject('Joe', TObject(1)); // This is where exception is raised
list.AddObject('Hans', TObject(2));
end;
这段代码在32位Windows目标上可以正常运行,但是在我的Nexus 7上运行(以调试模式)时会引发上述异常(当我不使用TStringList.AddObject时运行良好)。如果我在未调试的情况下运行该应用,则它会在Nexus上关闭。
这是Delphi Android的已知问题/局限性吗?是否有解决方法或建议的方法来获得相同的结果(不仅针对此玩具示例,而且通常使用AddObject)?
最佳答案
整个编程风格是Delphi 7时代的做事方式。但是自那以后,许多事情已经发生了变化。最具体地说,移动编译器使用ARC,他们将尝试破坏字符串列表中保存的对象。那解释了您看到的错误。
另一个更改是D2009中添加的对泛型的支持。现在,您应该为该任务使用类型安全的通用容器,而不是字符串列表。周围有很多,但让我们用Generics.Collections
的内置类展示一个示例。
您需要创建一个列表元素类型。它包含一个字符串和一个整数。
type
TMyItem = record
public
Name: string;
Age: Integer;
end;
让我们以一种简单的方式来制作新的:
function NewMyItem(const Name: string; const Age: Integer): TMyItem;
begin
Result.Name := Name;
Result.Age := Age;
end;
然后让我们列出它们:
var
List: TList<TMyItem>;
....
List := TList<TMyItem>.Create;
现在添加一些项目:
List.Add(NewMyItem('Joe', 1));
List.Add(NewMyItem('Hans', 2));