QTGraphicsExporter.SavePictureをスレッド内で使用するとアプリケーションが応答しなくなる事がある

最近QuickTimeが新しくなったせいか、既存のRbアプリでタイトルのような障害が発生する事があります。
割合深刻な問題な上、原因発見が結構困難な問題ですが、現状それらしい情報が上がっていないようなので
ここで報告しておきます。

公式の報告はまだありません。Yukiの環境に依存する問題である可能性があります。

情報をお持ちの方はコメント下さい。

障害の内容

QTGraphicsExporter.SavePictureメソッド使用後、アプリケーションが応答しなくなる

発生環境

私の環境を描いておきます:

  • Intel CPU
  • OS 10.5.1(1/25時点で最新)
  • QuickTime7.4(1/25時点で最新)
  • REALbasic 2006r3 - 2007r5(IDE/ビルド済み両方)
  • UnivasalBinary/PPC(=Rosetta経由)両方

再現性

上記の環境では、以下の条件で100%再現します:

  1. スレッド(Threadクラス)内でQTGraphicsExporter.SavePictureを呼ぶ
  2. QTGraphicsExporterがスレッド外から参照されている状態でスレッドの処理を抜ける
  3. QTGraphicsExporterへの参照が0になったタイミングで応答不能

要するに

スレッド内でQTGraphicsExporterを使ったあと、スレッドが先に終了*1するとダメ。

ダイアログ開いて設定を済ませた後のQTGraphicsExporterをスレッドに渡してバックグラウンドで処理する、
という使い方はわりと一般的だと思うのですが。

どうする?

QTGraphicsExporterをスレッド内で使い捨てにするのが一番安全。
スレッドにQTGraphicsExporterを渡した場合、Runする前*2に確実に全ての参照を切る実装をしないと危険です。

絵箱

直します。

フレームワーク内でQTGraphicsExporterをタライ回しにしている気配でいっぱい...

*1:「スレッドの終了=RbのThreadインスタンスの解放」ではないので注意。ThreadIDを見れば分かるけど、実際にはRunメソッドを抜けたタイミングでスレッド自体は終了している

*2:一般論として、排他制御しないかぎりスレッドの終了タイミングは管理できない。Run後にNilを代入して参照を切っても、タイミング次第で先にスレッドが終了してしまう可能性がある