我一直试图解决我们的NSOperation子类中的问题,我觉得它可能与我们的KVO手动更改通知有关。在更新NSOperation状态时,我检查过的所有来源似乎都会执行以下操作:
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
相比之下,我们这样做:
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = NO;
[self didChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isFinished = YES;
[self didChangeValueForKey:@"isFinished"];
有人可以告诉我为什么前者似乎是推荐的做法吗?
Apple的KVO文档似乎也推荐了第一种方法。不幸的是,他们无法解释原因。(https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html#//apple_ref/doc/uid/20002178-SW3)/
答案 0 :(得分:1)
原因在于,从概念上讲,操作正在将两种状态一起改变。您希望仅在为两个属性更新内部状态后才通知观察者,以便在处理通知时,观察者看到一致的状态。
如果你这样做:
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = NO;
[self didChangeValueForKey:@"isExecuting"];
然后观察者将在isExecuting
调用期间获得didChange...
属性的更改通知。如果他们检查其处理程序中的操作属性,他们可以看到操作没有执行(isExecuting
返回NO
)但还没有完成(isFinished
仍然返回NO
) 。这没有意义。观察者可以做一些奇怪的事情。
答案 1 :(得分:0)
我没有遵循模式
实施了NSOperation[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
而不是简单地做
self.executing = NO;
self.finished = YES;
..使用NSOperationQueues时没有问题(永不结束操作等)。似乎NSOperationQueue只听“IsFinished'确定NSOperation是否真正完成。这个答案更好地解释了。