iOS上で時間のかかる処理を実行する場合には、GCDを利用してバックグラウンド処理するのが効果的です。 ただ、GCDにはcancelの仕組みがないため、cancel方法は自分で実装する必要があります。
良くあるのは、viewのdidChange系通知を使用する場合です。ユーザレスポンスを高めるためにはdidChangeにはすぐ応答したいですが、ユーザの操作によってはdidChangeは連続して送られてきます。使用されないデータを計算するのは時間的にも消費電力的にも無駄になるため、最後の一回だけを実行することが望ましいです。
僕の場合には、下記のようなキャンセル状態を保存するクラスを作成し、それをGCDで実行するブロックに渡すようにしました。
@interface Sample : NSObject @property(readonly) BOOL isCanceled; -(void)cancel; @end @implementation Sample @synthesize isCanceled=_isCanceled; -(void)cancel { @synchronized(self){ _isCanceled = true; } } @end
新しくGCDに処理を投入する場合には、cancelFlagを生成してそれをブロックに渡します。もしすでに使用中のcancelFlagがある場合には、先にロックを取得した上でFlagをキャンセルしておきます。
-- ジョブは完了済みか、実行中 -- [cancelFlag cancel]; -- ジョブは完了済みか、キャンセル済み -- cancelFlag = [[Sample alloc]init];
GCDで実行するブロックの中では処理の合間にcancelFlagを確認します。この際に必ずしもロックは必要ありませんが、処理を完了する時には必ずロックを取得することで、ジョブの二重実行をさけることができます。
参考
0 件のコメント:
コメントを投稿