Referenceによる動的オブジェクト

レファレンスは、直接それを用いてヒープオブジェクトを生成することができます。ヒープオブジェクトというのは、はじめから辞書内に場所を確保しておく静的なオブジェクトではなく、必要に応じてメモリー上に動的に生成されるオブジェクトのことです。MopsではObjHandleなどの、いわばコンテナオブジェクトを使うのが普通ですが、このレファレンスもオブジェクトのコンテナのような働きをするということです。もっとも、ObjHandleの場合のように、クラスをあれこれ変えることはできません。

レファレンスを用いてヒープオブジェクトを生成するには、まず、レファレンスは特定のクラスのオブジェクトを参照するものとして宣言しなければなりません。つまり、"Any"ではいけないということです。生成するオブジェクトのクラスが特定できないからです。

例として、WINDOW+クラスでやってみましょう。
ref WINDOW+ ww+
宣言以後はもちろん、メッセージ伝達をコンパイルすることができます。ただし、メソッドの実行前にオブジェクトを生成しなければなりません。それは、
new> ww+
とすることで実行されます。コンパイル状態でも同じ構文です。これが実行されれば、MopsオブジェクトとしてのWindow+オブジェクトがヒープに生成されます。以後は、レファレンスに対するメッセージについては、そのオブジェクトに対してメソッドが実施されます。バインドは、静的オブジェクトのアドレスを格納した場合と全く同じです。通常は、バーチャルテーブルによる動的束縛、宣言時に "no_subclasses"とつけていれば静的束縛です。ついでながら、"no_subclasses"の有無にかかわらず、new>によって生成されるオブジェクトは、宣言されたクラスのオブジェクトになります。Windowクラスのreferenceにnew>を送ると、Windowクラスのオブジェクトが生成されるのであって、そのサブクラスのオブジェクトが生成されることはありません。念のため。

なお、レファレンスのクラスが、アレイなどの項目数が必要なものである場合には、"new>"の時にスタックにそれを与えてやる必要があります。例えば、8項目アレイなら、
Ref Array ArrayRef
....
8 new> ArrayRef
のような具合です。

ところで、レファレンスによる動的オブジェクトは、レファレンスカウントがついています。これは、その動的オブジェクトが、いくつのレファレンスから参照されているかを示しています。もちろん、最初に生成した段階では1です。このポインタを別のレファレンスにコピーしたときには、カウンタは1増えて2になります。レファレンスのコピーは次のように行います。
ref WINDOW+ ww+2
ww+ -> ww+2
こうすると、"ww+"を用いて生成された動的オブジェクトは、"ww+"と"ww+2"の二つのレファレンスから参照されるわけです。どちらのレファレンスに対するメッセージも、このオブジェクトに送られます。コピーからオブジェクトの属性を変更できないようにする機構のようなものは無いようです。自分で注意しろ、ということでしょう。まあ、Forth系にはありがちですね(^^;;)。

もちろん、2つより多いレファレンスからの参照も可能です。

レファレンスで生成された動的オブジェクトへの参照は、"release>"で切り離すことができます。上のような状態で、例えば、
release> ww+
とやると、レファレンス"ww+"の内容は無効なポインタに取り替えられ、動的オブジェクトとの参照関係は切れます。この際には、オブジェクト自体は廃棄されるわけではなく、レファレンスカウントが1減らされるに止まります。

"new>"もまた、既存のオブジェクトとの参照関係を切ります。これはつまり、一旦、"release>"を送って既存の関係を切り離してから、新しい動的オブジェクト生成して、そのポインタを格納する、という動作をするわけです。

レファレンスカウントが0になるということは、つまり、もうどのレファレンスも、そのオブジェクトのポインタを保持していないということを意味します。この状態になったときには、まず、オブジェクト自体に"Release:"が送られます。最後に残ったオブジェクト自体が占めるヒープ領域はガベージコレクタ(訳せば、ゴミ収集機)が探知して解放します。この時点で、すべて綺麗さっぱり掃除されることになるわけです。ガベージコレクタは、レファレンスカウントが0になるとすぐに呼び出されるわけではなくて、定期的に参照関係をチェックしています。そのときにカウントが0のものを見つければ解放する、ということです。とうぜん、若干、メモリー効率は落ちるわけですが、大したことではありません。ともかく、レファレンスによる動的オブジェクトには、その解放云々を気にしなくてよいという利点があるわけです。


関連項目:






最終更新:2018年12月26日 14:32