NSOperation のサブクラスを使用して、いくつかのバックグラウンド プロセスを実行しています。ユーザーがボタンをクリックしたときに操作をキャンセルしたい。
これが私の NSOperation サブクラスの外観です
- (id)init{
self = [super init];
if(self){
//initialization code goes here
_isFinished = NO;
_isExecuting = NO;
}
return self;
}
- (void)start
{
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
return;
}
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
//operation goes here
}
- (void)finish{
//releasing objects here
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
- (void)cancel{
[self willChangeValueForKey:@"isCancelled"];
[self didChangeValueForKey:@"isCancelled"];
[self finish];
}
これが、このクラスのオブジェクトをキューに追加し、KVO 通知をリッスンする方法です。
operationQueue = [[NSOperationQueue alloc] init]; [operationQueue setMaxConcurrentOperationCount:5]; [operationQueue addObserver:self forKeyPath:@"operations" options:0 context:&OperationsChangedContext];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == &OperationsChangedContext) {
NSLog(@"Queue size: %u", [[operationQueue operations] count]);
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
操作をキャンセルするには (たとえば、ボタンのクリックで)、-cancel を呼び出してみましたが、違いはありません。-finish も呼び出してみましたが、それでも何も変わりません。
操作をキューに追加するたびに、キューのサイズが増加するだけです。finish が呼び出されます (NSLog ステートメントを使用してチェックされます) が、操作は実際には終了しません。私はまだこれを正しく行っていると確信していません
誰かが私が間違っているところを教えてもらえますか?
どうもありがとう