Ios NSKVO操作已完成

Ios NSKVO操作已完成,ios,key-value-observing,nsoperation,Ios,Key Value Observing,Nsoperation,我正在尝试对NSO操作进行子类化,并从中读取一些示例, 他们说:当任务完成时,使用NSOperation的KVO来完成操作, 代码如下: [self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"] finished = YES; executing = NO; [self didChangeValueForKey:@"isFinished"]; [self didChangeVal

我正在尝试对NSO操作进行子类化,并从中读取一些示例, 他们说:当任务完成时,使用NSOperation的KVO来完成操作, 代码如下:

[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"]
finished = YES;
executing = NO;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
然后我会接到电话

- (BOOL) isFinished{
    return(finished);
}
有人能给我解释一下吗?为什么调用isFinished,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
在被告知其值的更改后,很可能被内部Apple代码调用。

首先,您不需要手动执行KVO通知。对于
NSOperation
子类KVO通知应自动发送,除非您的类通过实现
+automaticallyNotifiesObserversForKey
+automaticallyNotifiesObserversOf
退出自动KVO通知以返回否

NSOperation
子类不是很有用,除非它们被添加到
NSOperationQueue
。将操作添加到队列时,队列使用KVO观察指示状态更改的属性,例如
已完成
正在执行
已取消
,等等。请注意,这些属性不是
已完成
正在执行
,或
isCancelled
-这些是这些属性的合成get访问器的名称

在您的问题中,您包括以下代码:

[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"]
finished = YES;
executing = NO;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
这里要做的是为get访问器发送手动KVO通知,而不是要观察的属性。相反,这将完成您似乎想要做的事情:

[self setFinished:YES];
[self setExecuting:NO];
使用访问器方法,而不是直接访问实例变量。这将正确发送这些属性的自动更改通知

如果您对KVO有真正的妄想症,并且希望发送获取访问器密钥路径的通知,例如
isFinished
,请将您的属性注册为密钥路径的依赖项:

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

添加到quellish答案中,这是您覆盖执行、完成和取消的方式

//.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];

如何以及何时调用操作的dealloc funct?
dealloc
将在操作的引用计数达到0时调用,即当没有人拥有对它的引用时。酷,伙计,我给操作一个观察者,当操作完成时,我调用release并发生dealloc。非常感谢,顺便说一句,你提到了NSOperationQueue observe isFinished,apple code call isFinished,这是一个链,queue观察op finished,然后它告诉apple code调用isFinished,如果是,我只是通过[op start]运行op,没有队列,isFinished会正常调用。如果remove didChangeValueForKey、isFinished未调用且op无法释放,则这是不正确的。我将在读者的评论中介绍我们的讨论。作者最初手动调用KVO通知方法的方法是尝试管理关键路径之间的依赖关系。KVO有一种机制来实现这一点,这应该作为第一种手段使用。添加了关键路径依赖模式,以获得所需的
isFinished
(和其他)通知。