为什么NSOperation禁用自动键值观察? [英] Why does NSOperation disable automatic key-value observing?

查看:73
本文介绍了为什么NSOperation禁用自动键值观察?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用自定义的NSOperation子类时,我注意到[NSOperation automaticallyNotifiesObserversForKey]类方法(至少对于某些键路径返回NO)禁用了自动键值观察.因此,NSOperation子类内部的代码会被手动调用willChangeValueForKey:didChange…乱扔,这在网络上的许多代码示例中都是可见的.

When working with a custom NSOperation subclass I noticed that the automatic key-value observing is disabled by the [NSOperation automaticallyNotifiesObserversForKey] class method (which returns NO at least for some key paths). Because of that the code inside of NSOperation subclasses is littered by manual calls to willChangeValueForKey: and didChange…, as visible in many code samples on the web.

为什么NSOperation那样做?使用自动KVO支持,人们可以简单地声明操作生命周期标志(isExecuting等)的属性,并通过访问器触发KVO事件,即.以下代码:

Why does NSOperation do that? With automatic KVO support people could simply declare properties for the operation lifecycle flags (isExecuting etc.) and trigger the KVO events through the accessors, ie. the following code:

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

...可以替换为:

[self setIsExecuting:NO];
[self setIsFinished:YES];

在某处有陷阱吗?我只是改写了automaticallyNotifiesObserversForKey以返回YES,而且一切似乎正常.

Is there a catch somewhere? I just overrode the automaticallyNotifiesObserversForKey to return YES and things seem to work fine.

推荐答案

最可能的解释是kvo键与标准约定不匹配.通常,其中一种方法具有-isExecuting-setExecuting:之类的键路径为@"executing"的方法.在NSOperation的情况下,密钥路径改为@"isExecuting".

The most likely explanation is that the kvo keys don't match the standard conventions. Normally one has methods like -isExecuting and -setExecuting:, where the key path is @"executing". In the case of NSOperation, the key path is @"isExecuting" instead.

另一种可能性是,大多数NSOperations实际上没有名为-setIsExecuting:的方法来更改该值.相反,它们将执行/完成标志基于其他内部状态.在这种情况下,绝对需要使用显式的willChange/didChange通知.例如,如果我有一个包裹NSURLConnection的NSOperation,则我可能有2个ivars,一个名为data的目录,它保存下载的数据,一个名为connection的目录,它存储NSURLConnection,我可以这样实现getter:

The other possibility is that most NSOperations don't actually have a method named -setIsExecuting: to change that value. Instead, they base the executing/finished flags on other internal state. In this case, one absolutely needs to use the explicit willChange/didChange notifications. For example, if I have an NSOperation that wraps an NSURLConnection, I may have 2 ivars, one named data that holds the downloaded data, and one named connection which holds the NSURLConnection, and I may implement the getters like so:

- (BOOL)isExecuting {
    return (connection != nil);
}

- (BOOL)isFinished {
    return (data != nil && connection == nil);
}

现在我的-start方法可以使用

[self willChangeValueForKey:@"isExecuting"];
data = [[NSMutableData alloc] init]; // doesn't affect executing, but is used later
connection = [[NSURLConnection connectionWithRequest:request delegate:self] retain];
[self didChangeValueForKey:@"isExecuting"];

开始执行,

[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
[connection cancel];
[connection release];
connection = nil;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];

完成.

这篇关于为什么NSOperation禁用自动键值观察?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆