【问题标题】:[NSOperation cancelAllOperations]; does not stop the operation[NSOperation 取消所有操作];不停止操作
【发布时间】:2012-09-21 13:26:48
【问题描述】:

xCode 4.4.1 OSX 10.8.2,看起来像 [操作 cancelAllOperations];不工作

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSOperationQueue *operation = [[NSOperationQueue alloc] init];
    [operation setMaxConcurrentOperationCount: 1];
    [operation addOperationWithBlock: ^{
        for (unsigned i=0; i < 10000000; i++) {
            printf("%i\n",i);
           }
    }];
    sleep(1);
    if ([operation operationCount] > 0) {
        [operation cancelAllOperations];
    }
}

结果 9999999

【问题讨论】:

    标签: cocoa nsoperationqueue


    【解决方案1】:

    在您的块内,特别是在循环内,调用-isCancelled 进行操作。如果为真,则返回。

    NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
    [operationQueue setMaxConcurrentOperationCount: 1];
    
    NSBlockOperation *operation = [[NSBlockOperation alloc] init];
    __weak NSBlockOperation *weakOperation = operation;
    [operation addExecutionBlock: ^ {
        for (unsigned i=0; i < 10000000; i++) {
            if ([weakOperation isCancelled]) return;
            printf("%i\n",i);
        }
    }];
    [operationQueue addOperation:operation];
    
    sleep(1);
    
    if ([operationQueue operationCount] > 0) {
        [operationQueue cancelAllOperations];
    }
    

    队列不能随意停止操作的执行 - 如果某些共享资源被从未被清理的操作所使用怎么办?您有责任在已知操作被取消时有序地结束操作。来自Apple's docs

    一个操作对象负责调用isCancelled 如果方法返回 YES,则周期性地自行停止。

    【讨论】:

    • 所以在它完成之前没有办法停止操作?
    • 有 - 在代码中,您检查 isCancelled。如果它是真的,那么你停止执行。操作自行停止,队列只是告诉它取消。这有意义吗?
    • 值得注意的是,在 ARC 下,您必须对操作对象进行弱引用并使用它来检查 isCancelled,以避免保留循环。
    • @jrturton 感谢提醒我相应地更新了我的代码!
    • 这真的有效吗?根据 addExecutionBlock 的文档,指定的块不应对其执行环境做出任何假设。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多