You are here: Home / TinBlog / オートマタ、使って天国、作って地獄 orz part.2

オートマタ、使って天国、作って地獄 orz part.2

Posted by h2 at Mar 16, 2013 03:35 AM |
Filed under:
お試しプロジェクト、Hello World! が無事完成したので、続いて本命のアクションの製作、いってみよう。と、言いたいところなんだけど。そうは問屋が卸さないんだな、やっぱり。

前回に引き続き、オートマタのアクション製作。本命その1は、ディレクトリ内のファイルを列挙するアクションなので、プロジェクト名をEnumerateFilesとして、雛形のプロジェクトを準備。ここまでの流れは、ADCのAutomator Programming Guideに詳しく説明されているので割愛。

・・・と、ここまで準備していて、ふと気になった。上のガイドのなかにあるWriting the Action Codeの章では、プログラムのスタートポイント(実際の処理をプログラムする開始地点)として、AMBundleActionクラスで用意されている- (id)runWithInput:(id)input fromAction:(AMAction *)anAction error:(NSDictionary **)errorInfo;メソッドをオーバーライドするように案内されている。

ところが。そのAMBundleActionクラスのリファレンスを見てみると、メソッド一覧のなかにrunWithInput:fromAction:error:メソッドの案内が無い。代わりに、冒頭のSubclassing Notesに、こんな記載が。

To complete the implementation of this subclass, you must override runWithInput:fromAction:error: (declared by AMAction).

どうやら、該当メソッドはAMBundleActionの親クラスであるAMActionで定義されているので、そっちを見ろ、ということらしい。それでは、と、runWithInput:fromAction:error:のリンクをポチって見ると。

runWithInput:fromAction:error:

Requests the receiver to perform its task using the specified input from the specified action. (Deprecated in OS X v10.4.)

---Deprecated AMAction Methods

・・・・・・・・・・。ええ、またぞろdeprecatedですよ。

「こっちを見ろ」と言っておきながら、見た先で「実は廃止されました」って、なんなのこれ。しかも、OS X 10.4といえば、オートマタが初登場したバージョンじゃなかったっけか。初登場のバージョンで、いきなり廃止予告って、なんだそれ。何のこっちゃわからないので、とりあえずAMActionのリファレンスを攫ってみたところ、Controlling the Actionの項で、

runAsynchronouslyWithInput:

Causes Automator to wait for notification that the receiver has completed execution, which allows the receiver to perform an asynchronous operation.

というメソッドを発見。名前からして、入力データを非同期で処理するためのメソッドらしい。そういえば、Automator Programming Guideに、こんな記載があったな。

To improve runtime stability and give AppleScript-based actions access to resources such as Standard Additions, Automator has a threading architecture that puts different types of program activity on separate threads. Automator starts a workflow on a secondary thread (that is, a thread other than the main thread).

---Threading Architecture

要約すると、「安定性確保のため、オートマタのアクションは別スレッドで実行されます」とかなんとか。ということは、非同期実行させるためには、初期メソッドはrunAsynchronouslyWithInput:でいいのか?

ということで、早速実験。前回のHello Worldプロジェクトで、runWithInput:fromAction:error:のメソッドをrunAsynchronouslyWithInput:に変更して実行してみたところ、一応、変更前と同じように動作した。

・・・が。どうにも腑に落ちない。なぜ10.8のバージョンにもなって、雛形プロジェクトの初期オーバーライドメソッドがrunWithInput:fromAction:error:のままなのか。それと、実験中にXcodeのデバッグログにでてきた、こんなログ。

NSAlert is being used from a background thread, which is not safe.  This is probably going to crash sometimes. Break on void _NSAlertWarnUnsafeBackgroundThreadUsage() to debug.  This will be logged only once.  This may break in the future.

「(UIではない)別スレッドでAlertのダイアログ出しているけど、クラッシュの原因になるよ」という警告。まあ、runAsynchronouslyWithInput:というメソッド名と、Threading Architectureの記載からすれば、当然こうなるよね。

慣れていない人向けにフォローしておくと、画面表示に関わる処理については、OS X (iOSやAndroidでもそうだけど)では、速度を必要とするグラフィックメモリ処理の都合上、一律にメインスレッドで実行するようにしておかないと、往々にしてクラッシュ(強制終了)を引き起こすのですよ。

そして、これを読んでいて、ハタと思い出した。そういえばこれ、前のメソッドでも出ていたような。というわけで、オーバーライドするメソッドを、元のrunWithInput:fromAction:error:に戻して、再度実験。

すると、またまた同じ警告文が出てきたじゃありませんか。

・・・と、いうことは。そもそもAMBundleActionrunWithInput:fromAction:error:は、非同期の別スレッドで動作していた、って事ですかね、これ。

 

なんとも狐につままれた気分なので、もう一度Automator Programming Guideを紐解いてみる。と、

Automator invokes the runWithInput:fromAction:error:method of the action, passing it the output of the previous action as input.

---A New Workflow

新しいワークフローでは、runWithInput:fromAction:error:を、うんたらかんたら。

 

・・・・・・・・・・・。

それじゃあ、AMBundleActionの記載は、どーなってるのさ。と、小一時間問い詰めてやりたい。

いったいなんですか、この役所の窓口をたらい回しにされている感満載の無限ループ orz 。

 

・・・で。さんざん悩んだ挙げ句。結局、雛形プロジェクトで準備されている通り、runWithInput:fromAction:error:を使うことにしました。端から別スレッドで動いているみたいだし、問題なさそうだし、Guideでは使えって書いてあるわけだし。

この際、AMBundleActionの先の記載は無視するってことで。

ちなみに、このrunWithInput:fromAction:error:メソッドだけど、デバッガでブレークポイント仕掛けてやると[AMAction _runWithInputDeprecated:]から呼び出されていることがわかる(OS X 10.8のオートマタの場合)。この先もこのメソッドが動作するか否は、アップルの胸先三寸で決まる、ということだよね・・・

 

・・・・・・・・・・・。

勘弁してよ orz

Filed under:
« June 2019 »
June
SuMoTuWeThFrSa
1
2345678
9101112131415
16171819202122
23242526272829
30