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来观察指示状态改变的属性,例如finished
, executing
, cancelled
等。注意,这些不是isFinished
, isExecuting
或isCancelled
– 这些是合成获得这些属性的访问器。
在你的问题你包括这个代码:
[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合规性的一部分。