NSOperation KVO已经完成

我试图从一个NSOperationinheritance,并从中读取一些样本,他们说:当任务完成后,使用NSOperation的KVO完成操作,代码如下:

[self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"] finished = YES; executing = NO; [self didChangeValueForKey:@"isFinished"]; [self didChangeValueForKey:@"isExecuting"]; 

然后isFinished被调用

 - (BOOL) isFinished{ return(finished); } 

任何人都可以向我解释这一点? 为什么已经被调用,isFinished会完成操作? 如我所知,KVO手动需要[self didChangeValueForKey:@“isExecuting”]; 我没有看到代码像addobserver:和observeValueForKeyPath:

我写

  -(void)call { [self willChangeValueForKey:@"isVip"]; [self didChangeValueForKey:@"isVip"]; } -(void)isVip { NSLog(@"Im vip"); } 

当[自我呼叫]时isVip不被调用;

NSOperationQueue实现将观察操作的“isFinished”属性(使用KVO),以便知道何时将其从队列中移除。 isFinished在被告isFinished价值变化后很可能被内部Apple代码调用。

添加到冷静的答案,这是你将如何覆盖执行,完成,取消。

 //.m @interface MyOperation () //class extension, make these otherwise read-only properties read-write, we must synthesize @property(atomic, assign, readwrite, getter=isExecuting) BOOL executing; @property(atomic, assign, readwrite, getter=isFinished) BOOL finished; @property(atomic, assign, readwrite, getter=isCancelled) BOOL cancelled; @end @implementation CoreLocationOperation @synthesize executing, finished, cancelled; + (BOOL)automaticallyNotifiesObserversForKey { return YES; } + (NSSet *)keyPathsForValuesAffectingIsCancelled { NSSet *result = [NSSet setWithObject:@"cancelled"]; return result; } + (NSSet *)keyPathsForValuesAffectingIsExecuting { NSSet *result = [NSSet setWithObject:@"executing"]; return result; } + (NSSet *)keyPathsForValuesAffectingIsFinished { NSSet *result = [NSSet setWithObject:@"finished"]; return result; } - (void)start { //.. //You can use self.executing = YES; (note we can change executing which would otherwise be read-only because we synthesized our own ivar. [self setExecuting:YES]; ... } - (void)cancel { //.. //super will change the properties executing/finished for us or we can do it manually [super cancel]; ... } @end 

我认为这比清楚

 [self willChangeValueForKey:_NSURLOperationIsFinished]; [self setIsFinished:YES]; [self didChangeValueForKey:_NSURLOperationIsFinished]; 

首先,您不需要执行手动KVO通知。 对于一个NSOperation子类,KVO通知应该自动发送,除非你的类已经通过+automaticallyNotifiesObserversForKey NSOperation或者+automaticallyNotifiesObserversOf<Key> NSOperation +automaticallyNotifiesObserversOf<Key>返回NO来退出自动KVO通知。

NSOperation子类除非添加到NSOperationQueue否则不是很有用。 当一个操作被添加到队列中时,队列使用KVO来观察指示状态改变的属性,例如finishedexecutingcancelled等。注意,这些不是isFinishedisExecutingisCancelled – 这些是合成获得这些属性的访问器。

在你的问题你包括这个代码:

 [self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"] finished = YES; executing = NO; [self didChangeValueForKey:@"isFinished"]; [self didChangeValueForKey:@"isExecuting"]; 

你在这里做的是发送手动KVO通知获取访问者 ,而不是被观察的属性。 相反,这将完成你似乎正在尝试做的事情:

 [self setFinished:YES]; [self setExecuting:NO]; 

不是直接访问实例variables,而是使用访问器方法。 这将正确地发送这些属性的自动更改通知。

如果您对KVO 真正偏执狂 ,并且想要发送getForrent访问器关键path的通知,请将您的属性注册为关键path的依赖关系:

 + (NSSet *) keyPathsForValuesAffectingIsFinished { NSSet *result = [NSSet setWithObject:@"finished"]; return result; } 

注册依赖关系是KVO合规性的一部分。

Interesting Posts