我试图继承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
答案 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来观察指示状态更改的属性,例如finished
,executing
,cancelled
等。请注意,这些不是{ {1}},isFinished
或isExecuting
- 这些是这些属性的合成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