Help us understand the problem. What is going on with this article?

Delphi 10.4 Sydney の ARC 廃止ついて

Delphi 10.4 Sydney リリース

待望の Delphi 10.4 Sydney が発表されましたね!
(Community Edition はライセンス違反の商用使用が多いためリリース時期を遅らすそうです)

この記事ではメモリ管理モデルの変更である ARC の廃止について見ていきます。

ちなみに、同時に導入された Managed Record によってスマートポインタが実装できるようになったので、ARC が必要だった場合でも問題無いですね!これについては、また今度。

ARC 廃止

Delphi がモバイルコンパイラを搭載してから ARC (Automatic Reference Counting: 参照カウンタ)によるメモリ管理がサポートされてきました。
しかし、Delphi ユーザーは元々 ARC を積極的に使っていなかった&コンパイラが複雑になる問題があったため、まず Linux 版コンパイラで、そして 10.4 では全てのコンパイラで ARC が廃止されました。

ARCの実例
procedure ARC;
begin
  var Foo := TFoo.Create; 
  Foo.Bar; 
end; // ARC がサポートされていると、ここで Foo は解放される

Delphi 使いの方々は ARC を使わず try-finally ブロックで書いてましたよね。

ARCに頼らない書き方
procedure ARC;
begin
  var Foo := TFoo.Create; 
  try
    Foo.Bar; 
  finally
    Foo.Free;
  end;
end; 

ということで、この ARC の廃止で気になるトピックを 5 つほど紹介します。

1.ARC 廃止で TInterfacedObject は影響を受けない

タイトルで言いたいことを書きましたが、そういうことです。
以前 Linux 版の時にも書きましたが、皆が心配しているみたいなので。

DocWiki にも書いてありますね。

image.png

TInterfacedObjectは問題ない
type
  IFoo = interface
    procedure Hello;
  end;

  TFoo = class(TInterfacedObject, IFoo) // TInterfacedObject による参照カウンタを使う
  public
    procedure Hello;
  end;

procedure Bar;
begin
  var Foo: IFoo := TFoo.Create; // 型が IFoo になっていることに注意。
  Foo.Hello;                    // TInterfacedObject の Interface は今まで通り自動開放される
end;

2.ARC 廃止でモバイルプラットフォームでも AnsiString が使える

ARC 廃止に伴って AnsiString が全プラットフォームで使えるようになりました。
以下のコードをモバイル向けにコンパイルしようとすると 10.3 ではエラーになりますが、10.4 ではエラーになりません。

AnsiStringが使える
var
  Ansi: AnsiString; // 10.3 ではここでエラー, 10.4 は OK
begin
  Ansi := 'Hello ?';
  Writeln(Ansi);
  Readln;
end.

つまり、10.4 では TMarshall や、TMarshaller を使ったりしなくて良くなりました。

10.4ではAnsiStringのためにMashallerを使わなくて良い
var
  M: TMarshaller;
begin
  var P := M.AsAnsi('Hello ?').ToPointer;
  // Ansi文字列の処理を P に対して行う
end;

3.ARC 廃止で文字列のインデックスがまた変わった

おわー!?!?!?
ということで、ARC 廃止によって全コンパイラの文字列のインデックスが元に戻りました
つまり、Android や iOS でも、文字の先頭インデックスは 1 です!
ただし、TStringHelper.Chars は 0 インデックスのままです。

モバイルコンパイラでもインデックスは1
procedure TForm1.Button1Click(Sender: TObject);
begin
  var Str := 'Hello, Delphi 10.4!';
  Edit1.Text := Str[1];      // 10.4 では 'H' が返るが 10.3 では 'e' が返る
  Edit1.Text := Str.Chars[0] // 10.4 でも 10.3 でも 'H' が返る
end;

マイグレーションが楽になったりする…かも?
まあ、でも TStringHelper.Chars を使った方がいいのかな…?

4.DisposeOf の立場が無くなる

ARC が廃止されたため、DisposeOf を使わず Free で済むようになりました。

5.Weak 参照の立場が無くなる

こちらも ARC が無くなったので、最早参照カウントの増加もおきず、この Attribute は ARC に対しては必要無くなりました(Interface に対しては未だに有効です)。

6.AUTOREFCOUNT, NEXTGEN が未定義に

当然ですが AUTOREFCOUNT も未定義になりました。
そして、NEXTGEN も未定義になりました。

Delphi 10.4 Sydney の定義済みシンボルのページは、まだ更新されていないようです。
定義済みの条件シンボル

まとめ

勢い余って 6 個書きましたが、これからはコードがすっきりと書けそうですね。

pik
シリアルゲームズ取締役 エンバカデロ・テクノロジーズ Delphi MVP Delphi で iOS / Android / Windows / macOS / Linux のアプリを作ったりしてるみたい。 たまに C#, .NET, Unity も使ってます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした