「エンバカデロ技術文書ライブラリ」にある「ホワイトペーパー: モバイル開発のためのDelphi言語(PDF)」を読んだ。
既存のコードがDelphiの新しいコンパイラでも問題なく動作するように、今から準備できることをまとめてみた。
詳細についてはホワイトペーパーをご覧ください。
文字列を直接変更しない
問題のあるコード
str1[4] := 'O';
対策
コンパイラ指令 {$WARN IMMUTABLE_STRINGS ON} で警告を表示する。
文字列の結合にTStringBuilderクラスを使用する
モバイルプラットフォームでは、普通の文字列の連結コードはかなり遅くなる。
問題のあるコード
for l := 1 to MaxLoop do
str1 := str1 + str2;
対策
TStringBuilderを使用する。
sBuilder := TStringBuilder.Create(str1, str1.Length + str2.Length * MaxLoop);
for l := 1 to MaxLoop do
sBuilder.Append(str2);
文字列のインデックスは0から始める
Delphi XE4のモバイルコンパイラでは、文字列のインデックスは0から始まる。
問題のあるコード
s[2] := 'O';
対策
コンパイラ指令 {$ZEROBASEDSTRINGS ON} で文字列のインデックスを0から始める。(Delphi XE3以降)
Low()、High()を使用する
s[Low(s) + 1] := 'O';
TStringHelperを使用する。
TStringHelperは0から始める文字列インデックス方式を使用する。
with文は使わない
with文は非推奨となる
ジェネリックコンテナクラスを使用する
TListではなくジェネリックコンテナクラスを使用する。
文字列リストや名前/値ペアにはTStringListでなくジェネリックディクショナリを使用する。
問題のあるコード
var
sList: TStringList;
begin
sList.AddObject(aName, anObject);
対策
var
sDict: TDictionary<string, TMyObject>;
begin
sDict.Add(aName, anObject);
クロスプラットフォームユニットを優先的に使用する。
ファイル管理にはIOUtilsユニットを使用する。
できるだけAPIの直接呼び出しを避ける。MSXMLでなくADOM XMLを使用する。ソケットライブラリやWebライブラリでなくIndyを使用する。
例
uses System.IOUtils;
var
myfilename: string;
begin
myfilename := TPath.GetHomePath + PathDelim + 'Documents' + PathDelim +
'thefile.txt';
if TFile.Exists(myfilename) then
...
メモリの問題のチェック
ReportMemoryLeaksOnShutdownはWindowsのみ有効
対策
iOSではInstrumentsツールを使う。
解説動画:Apple Instruments and Delphi for iOS Movie | Daniel Magin's Logfile
CheckForCyclesで循環参照を検証する
var
MyComplex: TMyComplexClass;
begin
MyComplex := TMyComplexClass.Create;
MyComplex.fSimple.DoSomething;
CheckForCycles(MyComplex,
procedure(const ClassName: string; Reference: IntPtr;
const Stack: TStack<IntPtr>)
begin
Log('Object ' + IntToHex(Reference, 8) + ' of class ' + ClassName +
' has a cycle');
end);
end;