QMLの値型およびシーケンス型の参照

QMLの値型およびシーケンス型は、必然的に値渡しで渡されます。QMLのオブジェクト型とは対照的に、これらはそれ自体としてのアイデンティティを持たず、他のオブジェクトや値のプロパティとして、あるいはメソッドから返される値としてのみアクセス可能です。このようなアクセスが行われるたびに、暗黙的にコピーが作成されます。しかし、JavaScriptではすべてがオブジェクトです。 JavaScriptには値型という概念はありません。たとえば、JavaScriptで `font.bold = true ` を実行すると、font が何であれ、`font ` の `bold ` プロパティが設定されることが期待されます。しかし、次のコードスニペットを考えてみてください。

import QtQuick
Text {
    onSomethingHappened: font.bold = true
}

この場合、font が値型であることはわかっています。これにアクセスすると、Q_PROPERTY のゲッターが呼び出され、ローカルコピーが作成されます。その後、そのコピーに対してbold プロパティを設定することは可能ですが、通常、その変更はコピーにのみ影響し、元のQ_PROPERTY には反映されません。

この問題を解決するために、QMLでは「参照」という概念が提供されています。 プロパティから値型またはシーケンス型のインスタンスを取得すると、QMLエンジンは値そのものと併せてそのプロパティも記憶します。値が変更されると、その変更はプロパティに書き戻されます。これにより、個別のアイデンティティを持つオブジェクトのような挙動が実現され、上記のケースをはじめとする多くのケースが問題なく動作するようになります。

ただし、これはかなりコストがかかる可能性があります。シーケンスがQ_PROPERTY として公開されている場合、インデックスを使ってシーケンス内の任意の値にアクセスすると、プロパティからシーケンスデータ全体が読み込まれます。このシーケンスデータから、1つの要素が取得されます。同様に、シーケンス内の任意の値を変更すると、シーケンスデータが読み込まれます。 その後、変更が実行され、変更後のシーケンスがプロパティに書き戻されます。対象の型が暗黙的に共有されている場合、読み取り操作のオーバーヘッドは比較的軽微です。一方、変更操作では常に少なくとも1回のディープコピーが発生します。

Q_INVOKABLE 関数からシーケンスまたは値型のインスタンスを返せば、このようなオーバーヘッドを回避できます。戻り値はどのプロパティにも紐付けられていないため、書き戻されることはありません。

オブジェクト型のシーケンスは、デフォルトでQQmlListProperty として渡されます。QQmlListProperty は実際のコンテナではなく、あるシーケンシャルな記憶領域へのビュー、つまり参照にすぎません。したがって、QQmlListProperty はこの影響を受けません。ただし、QML_SEQUENTIAL_CONTAINER を使用して、オブジェクト用の他のシーケンス型を登録することは可能です。それらの型は影響を受けます。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.