[ios]NSOperationQueue︰ 取消操作后给的超时

发布时间: 2017/3/28 21:32:43
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

基本上,我想如果我要加入到队列的操作没有响应某些超时后执行取消︰

NSOperationQueue *   queue = ...

[self.queue addOperationWithBlock:^{
        // my block...
    } timeoutInSeconds:5.0 hasTimedOutWithBlock:^{
        // called after 5.0, operation should be canceled at the end
}];

感谢你们 !

解决方法 1:

你能像你想要的但我可能会建议将参数添加到第一个块的第一个块可以查查看是否操作被取消。

[queue addOperationWithBlock:^(NSOperation *operation) {

    // do something slow and synchronous here, 

    // if this consists of a loop, check (and act upon) `[operation isCancelled]` periodically 

} timeout:5.0 timeoutBlock:^{

    // what else to do when the timeout occurred

}];

也许你不需要检查 isCancelled ,但在一些情况下,你会 (一般为响应取消操作负担取决于手术本身),所以这可能是一个审慎的参数来添加。

不管怎么说,如果这是你想要的东西,你可能会做类似于以下内容︰

@implementation NSOperationQueue (Timeout)

- (NSOperation *)addOperationWithBlock:(void (^)(NSOperation *operation))block timeout:(CGFloat)timeout timeoutBlock:(void (^)(void))timeoutBlock
{
    NSBlockOperation *blockOperation = [[NSBlockOperation alloc] init];  // create operation
    NSBlockOperation __weak *weakOperation = blockOperation;             // prevent strong reference cycle

    // add call to caller's provided block, passing it a reference to this `operation`
    // so the caller can check to see if the operation was canceled (i.e. if it timed out)

    [blockOperation addExecutionBlock:^{
        block(weakOperation);
    }];

    // add the operation to this queue

    [self addOperation:blockOperation];

    // if unfinished after `timeout`, cancel it and call `timeoutBlock`

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // if still in existence, and unfinished, then cancel it and call `timeoutBlock`

        if (weakOperation && ![weakOperation isFinished]) {
            [weakOperation cancel];
            if (timeoutBlock) {
                timeoutBlock();
            }
        }
    });

    return blockOperation;
}

@end

该代码示例提供了,我必须承认,有一套很狭隘的情况在哪里像上述的东西可能有用。通常会更好地解决使用另一种模式。绝大多数时间,当你想要一个可取消的操作,您将实现 NSOperation 子类 (经常并发 NSOperation 子类)。请参阅定义自定义操作对象操作队列章的并发编程指南的详细信息。

赞助商