2011-02-10 12 views
17

私はNSOperationQueueのaddOperationWithBlockを使用しています。ブロック内から操作をキャンセルする必要があるかどうかを確認するにはどうすればよいですか?またはNSOperationのプロパティ/メソッドにアクセスできますか?addOperationWithBlockで作成した操作をキャンセルするにはどうすればよいですか?

[myOperationQueue addOperationWithBlock: ^{ 

    while (/* long running loop */) 
    { 
     // how to determine here if I need to cancel? 
     // for that matter, access any NSOperation properties/methods? 

    } 

}]; 

NSBlockOperationを使用するより良い方法はありますか?

答えて

49

より良い解決策は、NSBlockOperationを使用して、ローブロックではなくキューに追加することです。あなたのような何かができる:

だけでなく(あなたの操作をほとんどより多くの制御を与えて...と、さらにいくつかの NSOperation細かな点ながら、これはあなたがブロックを使用することができます
__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ 
    while(![operation isCancelled]){ 
    //Some long operation 
    } 
}]; 

[[self queue] addOperation:operation]; 

例えば、完了ブロックを追加する機能などの)。

+0

これはほぼ正確に私が望むものです。その特定のブロックでのみ動作します。私の場合、私のブロックは別のブロックを呼び、その時点で私はもう「操作」へのアクセス権を持っていないと思います。私は、NSOperationをサブライズすれば、私のケースがうまくいく唯一の方法だと思います。 – roocell

+0

私は自分のブロックを介して操作を渡すことで私のケースを解決することができました。ありがとう - 私はNSOperationのサブクラスを避けるので、私はこのアプローチが好きです。 – roocell

+0

このソリューションは素晴らしいです。私が持っている唯一の小さな質問は、変数 'operation'に__blockタグを付ける必要がありますか?変数の値をブロック内で変更する必要がないので、私はそうは思わない。 – Jake

2

ブロック内にある操作をキャンセルする必要があるかどうかは、実際には確認できません。それがブロック内にあり、キャンセルされる予定の場合、キャンセルされます。ブロックがNSOperationインスタンスそのものではないため、NSOperationプロパティにアクセスすることはできません。

例コード:

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSOperationQueue *q = [[NSOperationQueue alloc] init]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:10]; 
     NSLog(@"Block 1"); 
    }]; 
    [q addOperationWithBlock:^{ 
     [NSThread sleepForTimeInterval:3]; 
     NSLog(@"Block 2"); 
    }]; 
    [q cancelAllOperations]; 
    [NSThread sleepForTimeInterval:15]; 

    [pool drain]; 
    return 0; 
} 

あなたが期待するようcancelAllOperationsはその後、ブロックの火を呼んで削除した場合。

操作のキャンセル状態を細かく制御し、NSOperationQueueと相互作用する必要がある場合は、NSBlockOperationではなくNSOperationを使用するほうがよいとお勧めします。 NSOperationをサブクラス化してこれを達成することができます。

関連する問題