【问题标题】:NSOperation cancel and NSOperationQueueNSOperation 取消和 NSOperationQueue
【发布时间】:2015-10-30 19:31:42
【问题描述】:

我想了解NSOperation 子类的正确行为是什么。 我的子类具有不同的isReady 条件。是的,如果操作被取消,我会签入代码并采取相应措施。这在操作执行时非常有用。它停止任务,将finished 设置为true,然后从队列中删除。但是它的依赖关系呢?它们还没有执行,所以它们永远停留在cancelled 状态下的NSOperationQueue

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

【问题讨论】:

  • 如果b依赖于ab将在a.finished == trueb.ready == true之后执行
  • 你没有得到问题。依赖行为是明确的。不清楚的是我应该为取消逻辑做什么。如果 b 依赖于 a,a 正在执行并被取消,b 也将被取消,但 ready 不能为 true,因此队列不会从数组中删除操作。那就是问题所在。我现在感兴趣的是操作尚未开始时取消的逻辑。谢谢。
  • 你叫哪个canceloperationQueue.cancelAllOperations()a.cancel()
  • 我有一个被取消的操作。无论哪种方式。取消方法被调用。依赖项应该怎么办?
  • 会执行依赖的操作。不管a是否被取消。您应该将operation.finished==true 设置为最终状态以使NSOperationQueue 删除operation。只要准备好开始operation,就应该设置.ready==true。在operation的生命周期中,你应该经常检查.cancelled,每当.cancelled == true,你应该停止operation并设置.finished == true

标签: ios objective-c swift nsoperation nsoperationqueue


【解决方案1】:

将执行相关操作。不管a是否被取消。

您应该将operation.finished==true 设置为最终状态以使NSOperationQueue 删除operation

您应该在准备好开始operation 时设置.ready==true

operation的生命周期中,你应该经常检查.cancelled.cancelled == true,你应该停止operation并设置.finished == true

【讨论】:

    【解决方案2】:

    我刚刚自己处理了这个问题。我不明白为什么当我取消我的NSOperation 子类时,它从未从NSOperationQueue 中删除。事实证明,我重写的 isReady 方法是罪魁祸首。 isReady 方法正在检查超级实现以及是否设置了属性,但它没有设置,这就是操作被取消的原因。但是,显然如果NSOperation 实例从未达到就绪状态,即使它被取消,NSOperationQueue 也不会删除该操作,直到它达到就绪状态。因此,解决方案是使用 isCancelled 属性值或您的自定义准备条件。或者,您可以更改逻辑以使操作始终就绪,但如果您的就绪条件不满足,则在 main 方法中不执行任何操作,具体取决于您的应用程序逻辑。

    例子:

    // 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 article 提供上述 KVO 相关代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多