知らずに回る Run Loop にご用心
- Apple
- ソフトウェア
- 開発
CotEditor 2.1.6 リリース!
以前記事を書いて紹介したように(→ 2015.2.19)何年も愛用している OS X 用プレーンテキストエディタである CotEditor。最新バージョンの 2.1.6 がリリースされた。
変更点を見てみると:
いくつか前のバージョンから保存時にフリーズするという問題があったのだけど、ほとんどの人はこれで直ると思います。
...という自慢でした。😤
-[NSTask waitUntilExit] の罠
自慢するだけなのもあれなので、今回の問題を引き起こしていた原因を同じバグで悩んでいる開発者のためにメモしておく。
CotEditor ではファイルの読み書きに authopen
というコマンドを使うような構造になっているのだけど、それを Cocoa から呼び出すために NSTask
というクラスが使われている。保存するデータをそこに投げたあと、処理を待つために呼ばれていたのが -waitUntilExit
というメソッド。
waitUntilExit という名前の通り、アプリケーションの処理を休んでコマンドが終了するのを待ってくれるものかと思いきや、ヘッダファイルのコメントを読むと罠があった。
// poll the runLoop in defaultMode until task completes
Run Loop が回るらしい。...ということはこの待ち時間の間、先にセットされていたタイマーの時間が来たらその処理が次々と割り込んでくることになる!
CotEditor の場合、ファイルの保存で authopen
が処理をしている中、その処理を待つ間に自動保存のタイマーが発動してしまい、予期せぬタイミングでもう一つの保存が実行されてしまっていた。それが結果的にフリーズを引き起こしていたのだ。
対策は簡単で、このメソッドを使わず単純なループで待つようにすればいい:
while (task.isRunning) {
usleep(200);
}
Wait 処理を使うときはどんな仕組みで待っているのか注意しましょう。
Share
リンクも共有もお気軽に。記事を書くモチベーションの向上に役立てます。