タイトル : Re: PowerPointのオブジェクト開放ができません 投稿日 : 2009/08/26(Wed) 22:28 投稿者 : Hongliang
列挙時は少々ややこしいことになりますね。 For Each は、コンパイル時に GetEnumerator の呼び出しに変換されます。 例えば For Each mySlide In mySlides Next というソースは、大雑把に言って Dim enumerator As IEnumerator = mySlides.GetEnumerator() While enumerator.MoveNext() Dim mySlide As Object = enumerator.Current End While というコードになります。IEnumerator は列挙子と呼ばれます。 このとき、ReleaseComObject で解放する必要がある参照は、 ・mySlides が 1 つ ・mySlide が列挙されるごとにそれぞれ 1 つずつ 持っているのは自明ですが、そのほかに GetEnumerator を 1 回呼び出したとき、 ・enumerator が 1 つ ・mySlides が追加で 1 つ 増えることになります。 mySlides に関しては単純に ReleaseComObject の呼び出す数を 1 回増やすだけでも なんとかなりますが、 enumerator の方については、For Each 構文を使った場合 For Each に完全に隠蔽されているので、解放できないと言うことになってしまいます。 ですので、For Each は使用せず、GetEnumerator 及び While ループを使う必要があります。 また、この GetEnumerator で取得した IEnumerator は、 ラップされたマネージなクラスインスタンス(非 COM オブジェクト)だと思います。 // Marshal.IsComObject メソッドで確認してみてください。 IEnumerator 自体が COM オブジェクトでないのであれば、 ReleaseComObject に直接渡すことはできません。 その場合、代わりにこの IEnumerator は ICustomAdapter インターフェイスも実装しているはずです。 enumerator を ICustomAdapter に TryCast してその GetUnderlyingObject メソッドを呼び出せば、 この列挙子の COM オブジェクト実体が取得でき、ReleaseComObject に渡すことができます。 あと気になるところとしては、 ローカル変数に Nothing を代入する意味は(ほぼ)無いってことでしょうかね。 |