Как аннулировать работу, созданную с помощью addOperationWithBlock?
Я использую NSOperationQueue addOperationWithBlock. Изнутри блока, как я могу проверить, должен ли я отменить операцию? Или получить доступ к любым свойствам/методам NSOperation?
[myOperationQueue addOperationWithBlock: ^{
while ( /* long running loop */ )
{
// how to determine here if I need to cancel?
// for that matter, access any NSOperation properties/methods?
}
}];
Является ли лучший способ сделать это для использования NSBlockOperation?
Ответы
Ответ 1
Лучшим решением может быть использование NSBlockOperation
и добавление этого в очередь вместо необработанного блока. Вы можете сделать что-то вроде:
__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
while(![operation isCancelled]){
//Some long operation
}
}];
[[self queue] addOperation:operation];
Это позволяет вам использовать блоки, давая вам немного больше контроля над операцией... и еще несколько тонкостей NSOperation
(например, возможность добавления блоков блокировки, например).
Ответ 2
Вы не можете проверить, нужно ли отменять операцию, если она находится в блоке. Если он в блоке и должен быть отменен, он отменяется. Доступ к свойствам NSOperation невозможен, поскольку блок не является экземпляром NSOperation per se.
Пример кода:
#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, вам было бы лучше использовать NSOperation, а не NSBlockOperation. Вы можете подклассифицировать NSOperation для выполнения этого.