NSOperation KVO完成

时间:2013-08-27 08:37:43

标签: ios key-value-observing nsoperation

我试图继承NSOperation,并从中读取一些样本, 他们说:当任务结束时,使用NSOperation的KVO完成操作, 代码在这里:

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

然后isFinished被称为

- (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");
}
执行[self call];

时,不会调用

isVip

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

添加到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];

答案 2 :(得分:-2)

首先,您不需要进行手动KVO通知。对于NSOperation子类,KVO通知应自动发送,除非您的班级通过实施+automaticallyNotifiesObserversForKey+automaticallyNotifiesObserversOf<Key>选择退出NO来退出自动KVO通知。

NSOperation子类除非添加到NSOperationQueue,否则不是很有用。将操作添加到队列时,队列使用KVO来观察指示状态更改的属性,例如finishedexecutingcancelled等。请注意,这些不是{ {1}},isFinishedisExecuting - 这些是这些属性的合成get访问器的名称。

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

isCancelled

您在此处所做的是为获取访问者发送手动KVO通知,而不是正在观察的属性。相反,这将完成你似乎想要做的事情:

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

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

如果您对KVO 真正偏执并希望发送get访问者密钥路径(例如[self setFinished:YES]; [self setExecuting:NO]; )的通知,请将您的属性注册为关键路径的依赖项:

isFinished

Registering dependencies is part of KVO compliance.