QMLの値型とシーケンス参照
QML 値型と QML シーケンス型は必然的に値で渡されます。QML オブジェクト型とは対照的に、それ自身は ID を持たず、他のオブジェクトや値のプロパティとして、あるいはメソッドから返される値としてのみアクセスすることができます。このようなアクセスは暗黙のうちにコピーを生成します。しかし、JavaScript ではすべてがオブジェクトです。JavaScriptには値型という概念はありません。例えば、JavaScriptでfont.bold = true
を実行した場合、font
が何であろうと、font
のbold
プロパティが設定されることを期待します。しかし、次のコード・スニペットを考えてみよう:
import QtQuick Text { onSomethingHappened: font.bold = true }
この場合、font
が値型であることがわかっています。この場合、Q_PROPERTY が値型であることはわかっています。この値型にアクセスすると、Q_PROPERTY のゲッターを呼び出すことでローカルコピーが作成されます。その後、bold
プロパティを設定することができますが、通常はコピーにのみ影響し、元の には影響しません。
この問題を解決するために、QMLには参照という概念があります。あるプロパティから値やシーケンス型のインスタンスを取得すると、 QMLエンジンは値そのものとともにそのプロパティを記憶します。値が変更されると、その値はプロパティに書き戻されます。これによって、あたかもオブジェクトが別個に存在しているかのような錯覚に陥り、上記のようなケースや他の多くのケースをうまく機能させることができるのです。
しかし、これはかなり高くつく可能性がある。シーケンスがQ_PROPERTY として公開されている場合、インデックスによってシーケンス内の任意の値にアクセスすると、シーケンスデータ全体がプロパティから読み込まれます。そして、このシーケンスデータから1つの要素を取得します。同様に、シーケンス内の任意の値を変更すると、シーケンスデータが読み込まれる。そして変更が実行され、変更されたシーケンスがプロパティに書き戻される。読み取り操作は、その型が暗黙的に共有されていれば比較的安価に行うことができます。変更は常に少なくとも1つのディープコピーを発生させます。
Q_INVOKABLE 関数からシーケンスや値型のインスタンスを返すと、このようなオーバーヘッドを避けることができます。戻り値はどのプロパティにもアタッチされず、書き戻されることもありません。
オブジェクト型のシーケンスは、デフォルトではQQmlListProperty として渡されます。QQmlListProperty は実際のコンテナではなく、シーケンシャルなストレージへのビュー(参照)にすぎません。したがって、QQmlListProperty はこの影響を受けない。しかし、QML_SEQUENTIAL_CONTAINER を使用して、オブジェクトに他のシーケンスタイプを登録することができます。それらは影響を受けます。
本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。