[英]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.