BBAsyncTask その1

さて、せっかくなのでBBAsyncTaskを作っていこう。

ゴールはAndroidのAsyncTaskのようなバックグラウンドスレッドで重い主処理を動かしつつ、メインスレッドと同期してGUIを更新する処理をその前後に挟める機能を持つ、いわゆる"Background Worker"である。

iOSの場合、バックグラウンドスレッドでの処理は仕組みを持つまでもなく、performSelectorを使うことで簡単に実現できる。

[self performSelectorInBackground:@selector(executeTask:) withObject:foo];
- (void)executeTask:(id)arg
{
  //バックグラウンドスレッドで処理
}

がしかし、メインスレッドとの同期をどうするか、GUIの更新をどうするか等の対応を一貫して書きたいために、敢えて用意することにした。

前回書いたプロトコルには、主処理と後処理のためのインタフェースを持っていたが、そこに更に前処理を追加する。また、Java(Android)の場合、同クラスはGenericsに対応しており型に合致した引数を使って具象クラスを書けるが、Objective-Cでは残念ながらGenericsにはまだ対応していないので、引数には単純にidを持たせるようにする。

BBAsyncTaskProtocol.h
@protocol BBAsyncTaskProtocol <NSObject>
@required
 - (id)executeInBackgound:(id)param; 
@optional
 - (void)preExecute:(id)param;
 - (void)postExecute:(id)executeResult;
@end

処理順は

1. -preExecute
2. -executeInBackgound
3. -postExecute

となるが、開発者側が実装する必要があるのは-executeInBackgoundだけであり、他の-preExecuteと-postExecuteは実装された場合にのみ実行されるようにする。なのでそれぞれに対して必須か任意かの指定をしてある。また-preExecuteのパラメタは-executeInBackgoundが呼ばれた際のものと同じであり、更に-postExecuteのパラメタは-executeInBackgoundの実行後の戻り値としたい。

実装上のポイントは、実装されるかどうか判らない前処理と後処理をどのように呼び出すのか。プロトコルとして制約しているのは-executeInBackgoundだけであり、このメソッドが呼ばれたことを処理の実行前に検知して前処理と後処理を挿入する必要がある訳だ。
また、非同期処理をどのように実装するかもポイントになるだろう。

勘の良い方はこの要件で実装にどのような仕組みを用いるか、想像が付いたことだろう。
具体的な実装は明日以降、少しずつ書いていく予定だ。