ここでもコンテナとしてはObjHandleを前提とします。
ヒープオブジェクトを廃棄するときに考えなければならないことは大別して二つあります。まず、そのオブジェクト自体が
インスタンス変数(のインスタンス変数のインスタンス変数.....)としてヒープに領域を確保している場合があるので、その解放をしなければなりません。それから、そのオブジェクトのデータ領域自体のために確保してあるヒープ領域も解放することになります。
はじめのインスタンス変数系列が確保している領域の解放は、ヒープオブジェクトが属するクラスのRELEASE:メソッドが面倒を見ているはずです。自分でクラスを作るときには、そのことに注意しなければなりません。最後のオブジェクト領域自体の解放は、コンテナのメソッドを経由することになります。
ところが、ObjHandleクラスのRELEASEOBJ:メソッドは、格納しているオブジェクト自体へもRELEASE:メッセージを送ってくれます。これはLate Bind(動的束縛)なので、どんなクラスのオブジェクトでも、適切なクラスのRELEASE:メソッドをバインドしてくれます。ですから、ヒープオブジェクトの属するクラスのRELEASE:メソッドが適切に書かれていれば、インスタンス変数系列の保持している領域は適切に解放されます。その後で、オブジェクトのデータ領域全体を解放します。これは、"Handle"に対する"RELEASE:"ということになります。
RELEASEOBJ: MyDynamicObj
これは便利ですが、場合によっては不都合が出る場合もあります。例えば、クラスによっては、既にRELEASE:されたインスタンスに、再び"RELEASE:"メッセージを送るとクラッシュする危険があるものもあります。この場合には、不用意にObjHandleに"RELEASE:"メッセージを送ってしまうと、クラッシュすることになってしまいます。ヒープオブジェクトが既にRELEASE:されている場合には、ObjHandleに対しては、強制的にHandleクラスのメソッドをバインドする"RELEASE:"メッセージを送る必要があります。
MyDynamicObj RELEASE: class_as> HANDLE
逆に、ヒープオブジェクトはRELEASE:しても、オブジェクトのデータ領域だけはヒープ上に残しておきたい場合もあるでしょう。そのようなときには、もちろん"OBJ:"メッセージを経由して、そのクラスのRELEASE:をバインドすることになります。ただし、オブジェクトの"RELEASE:"は、一般にはオブジェクトのデータ領域の初期化ではないので注意してください。
オブジェクト自体のRELEASE:とコンテナオブジェクトのRELEASE:には、上のように若干面倒な場面が起こり得ます。これは、一般には、各オブジェクトのクラスの方で、二重にRELEASE:されても問題が起きないように工夫しておくことで回避できます。特に、システムオブジェクト(ヒープも含む)をnew:によって獲得するオブジェクトについては、きちんと設計しておくべきでしょう。たとえば、一回RELEASE:を受けたなら、システムオブジェクトを開放後に、レフェレンスの値をnilpや0などの特別なものにしておき、すでにレファレンスがそのような値の場合には、何もしないようにする、というのが最も簡単な方法です。
関連項目:
最終更新:2019年02月28日 23:13