繁体   English   中英

NSOperation取消和NSOperationQueue

[英]NSOperation cancel and NSOperationQueue

我想了解NSOperation子类的正确行为是什么。 我的子类具有不同的isReady条件。 是的,我检查代码是否取消了操作,因此采取了行动。 在执行操作时,这很棒。 它停止其任务,将finished设置为true,并将其从队列中删除。 但是它的依赖性如何呢? 它们尚未执行,因此它们永远处于NSOperationQueue处于cancelled状态。

我应该设置ready = true的取消操作,以便将队列调用将在执行设置,并立即完成任务的启动方法设置finished为真?

相关操作将被执行。 无论a是否取消。

您应该在最终状态下设置operation.finished==true ,以使NSOperationQueue删除该operation

只要准备开始operation ,就应该设置.ready==true

operation生命周期中,每当.cancelled == true时,您应经常检查.cancelled ,应停止operation并设置.finished == true

我自己解决了这个问题。 我不明白为什么当我取消NSOperation子类时,从未将其从NSOperationQueue删除。 事实证明,我应该重写的isReady方法。 isReady方法正在检查超级实现,以及是否设置了属性(是否未设置),这就是为什么操作被取消的原因。 但是,显然,如果NSOperation实例从未达到就绪状态(即使已取消),则NSOperationQueue在达到就绪状态之前不会删除该操作。 因此,解决方案是将您的自定义条件与isCancelled属性值进行“或”运算。 另外,您可以更改逻辑以使操作始终准备就绪,但是如果不满足准备条件,则在主方法中不执行任何操作,具体取决于应用程序逻辑。

例:

// for proper KVO compliance
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    NSSet *keys = [super keyPathsForValuesAffectingValueForKey:key];

    NSString *readyKey = NSStringFromSelector(@selector(isReady));
    if ([readyKey isEqualToString:key]) {
        keys = [keys setByAddingObjectsFromArray:@[NSStringFromSelector(@selector(url)), NSStringFromSelector(@selector(isCancelled))]];
    }

    return keys;
}

- (BOOL)isReady
{
    return (this.url != nil || this.isCancelled) && super.isReady;
}

- (void)setUrl:(NSURL *)url
{
    if (self.url == url) {
        return;
    }

    NSString *urlKey = NSStringFromSelector(@selector(url));

    [self willChangeValueForKey:urlKey];

    _url = url;

    [self didChangeValueForKey:urlKey];
}

感谢NSHipster的KVO文章提供了以上与KVO相关的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM