Main Content

プロパティ値が変化しない場合の代入

値が変化しない場合の AbortSet

プロパティ値を設定すると MATLAB® はプロパティ PreSetPostSet のイベントをトリガーし、プロパティの set メソッド (定義されている場合) を呼び出してプロパティ値を設定します。これらのアクションは、プロパティの現在値が新しい値と同じ場合でも発生します。

プロパティの AbortSet 属性を true に設定すると、これらのアクションを回避できます。AbortSet が有効になっている場合、MATLAB はプロパティの現在値とプロパティに代入される新しい値を比較します。新しい値が現在値と同じ場合、MATLAB は以下を行いません。

  • プロパティ値の設定。

  • PreSet イベントと PostSet イベントのトリガー。

  • プロパティの set メソッドの呼び出し (存在する場合)。

値を比較するために、MATLAB はプロパティの現在値を取得しなければなりません。現在値を取得することにより、プロパティの get メソッド (get.Property) が実行されます (存在する場合)。プロパティの get メソッドを呼び出すときに発生するエラーは、MATLAB が現在値を変更しない場合でもユーザーに表示されます。

メモ

AbortSet 属性は、ハンドル クラスで定義されているプロパティでのみ機能します。値クラスで使用することはできません。

MATLAB が値を比較する方法

MATLAB は関数 isequal を使用して、プロパティの現在値が新しい値と同じかどうかを判定します。AbortSet 属性を使用しているときに特定の値が等価として評価されるかどうかを判断するには、関数 isequal のドキュメンテーションまたはプロパティ値のクラスに対してオーバーロードされた isequal メソッドを参照してください。

AbortSet を使用する場合

AbortSet 属性を使用すると、プロパティの現在値と新しい値の比較でいくらかのオーバーヘッドが発生します。AbortSet 属性を使用すると、割り当てが行われる前に現在の値と割り当てられる値が常に比較されるため、すべてのプロパティの割り当てが遅くなる可能性があります。AbortSet 属性は、次の場合に最も役立ちます。

  • プロパティ値が変化しない場合は、PreSet イベントと PostSet イベントの通知およびリスナー コールバックの実行を回避する。

  • プロパティ値を設定するコストの方が、現在のプロパティ値と割り当てられる値を比較するコストよりも大きくなるため、プロパティへのすべての割り当てで比較にコストがかかっても構わない場合。

AbortSet の実装

以下の例は、AbortSet 属性の動作方法を示します。AbortTheSet クラスは、PreGetPreSetPostGet および PostSet イベントに対するリスナーをもつ、プロパティ PropOne を定義し、AbortSet 属性を有効にします。

メモ

このクラスを使用するには、AbortTheSet クラスを MATLAB パス上にあるフォルダー内で同じ名前のファイルに保存してください。

classdef AbortTheSet < handle
    properties (SetObservable, GetObservable, AbortSet)
        PropOne = 7
    end
    methods
        function obj = AbortTheSet
            addlistener(obj,'PropOne','PreGet',@obj.getPrePropEvt);
            addlistener(obj,'PropOne','PreSet',@obj.setPrePropEvt);
            addlistener(obj,'PropOne','PostGet',@obj.getPostPropEvt);
            addlistener(obj,'PropOne','PostSet',@obj.setPostPropEvt);
        end
        function propval = get.PropOne(obj)
            disp('get.PropOne called')
            propval = obj.PropOne;
        end
        function set.PropOne(obj,val)
            disp('set.PropOne called')
            obj.PropOne = val;
        end
        function getPrePropEvt(obj,src,evnt)
            disp ('Pre-get event triggered')
            % ...
        end
        function setPrePropEvt(obj,src,evnt)
            disp ('Pre-set event triggered')
            % ...
        end
        function getPostPropEvt(obj,src,evnt)
            disp ('Post-get event triggered')
            % ...
        end
        function setPostPropEvt(obj,src,evnt)
            disp ('Post-set event triggered')
            % ...
        end
        function disp(obj)
            % Overload disp to avoid accessing property
            disp (class(obj))
        end
    end
end

このクラスは、PropOne プロパティに対して初期値 7 を指定します。したがって、オブジェクトを作成し、プロパティ値 7 を割り当てる場合、PreSet イベントをトリガーする必要はありません。ただし、割り当てられた値と比較するために、getPropOne メソッドが呼び出されて、プロパティの現在の値が取得されます。

obj = AbortTheSet;
obj.PropOne = 7;
get.PropOne called

7 以外の値を指定すると、MATLAB は以下の手順を実行します。

  • 現在のプロパティ値を取得する

  • PreSet イベントをトリガーする

  • プロパティを割り当てられた値に設定する

  • PostSet イベントをトリガーする

obj = AbortTheSet;
obj.PropOne = 9;
get.PropOne called
Pre-set event triggered
set.PropOne called
Post-set event triggered

プロパティ値をクエリすると、PreGet イベントと PostGet イベントがトリガーされます。

obj.PropOne
Pre-get event triggered
get.PropOne called
Post-get event triggered

ans =

     9

AbortSet とプロパティ検証の使用

クラスのプロパティ定義でプロパティ検証と AbortSet を使用する場合、MATLAB は現在の値と割り当てられている値を比較する前に、プロパティ検証を評価します。たとえば、PropOne プロパティに 1 行 3 列のサイズ制限を追加するために AbortTheSet クラスを修正します。

classdef AbortTheSet < handle
    properties (SetObservable, GetObservable, AbortSet)
        % Restrict size to 1-by-3
        % ***********************
        PropOne (1,3) = [7 7 7]
        % ***********************
    end
    methods
        function obj = AbortTheSet
            addlistener(obj,'PropOne','PreGet',@obj.getPrePropEvt);
            addlistener(obj,'PropOne','PreSet',@obj.setPrePropEvt);
            addlistener(obj,'PropOne','PostGet',@obj.getPostPropEvt);
            addlistener(obj,'PropOne','PostSet',@obj.setPostPropEvt);
        end
        function propval = get.PropOne(obj)
            disp('get.PropOne called')
            propval = obj.PropOne;
        end
        function set.PropOne(obj,val)
            disp('set.PropOne called')
            obj.PropOne = val;
        end
        function getPrePropEvt(obj,src,evnt)
            disp ('Pre-get event triggered')
            % ...
        end
        function setPrePropEvt(obj,src,evnt)
            disp ('Pre-set event triggered')
            % ...
        end
        function getPostPropEvt(obj,src,evnt)
            disp ('Post-get event triggered')
            % ...
        end
        function setPostPropEvt(obj,src,evnt)
            disp ('Post-set event triggered')
            % ...
        end
        function disp(obj)
            % Overload disp to avoid accessing property
            disp (class(obj))
        end
    end
end

MATLAB はスカラー拡張を適用してサイズ制限を満たすため、以下の割り当てによって PreSet または PostSet イベントがトリガーされることはありません。

obj = AbortTheSet;
obj.PropOne = 7;
get.PropOne called
obj.PropOne
Pre-get event triggered
get.PropOne called
Post-get event triggered

ans =

     7     7     7

プロパティ検証の詳細については、プロパティ値の検証を参照してください。

関連するトピック