简体   繁体   English

键值观察NSCache

[英]Key-Value Observing NSCache

I want to get notified when the object corresponding to a certain key in an NSCache instance changes. 我希望在NSCache实例中某个键对应的对象发生更改时收到通知。 I've tried using Key-Value Observing without luck (the console doesn't log anything). 我试过没有运气使用键值观察(控制台不记录任何东西)。

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.cache addObserver:self forKeyPath:@"myKey" options:NSKeyValueObservingOptionNew context:NULL];
    [self.cache setObject:@"myObject" forKey:@"myKey"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"KEYPATH CHANGED: %@", keyPath);
}

How can I observe the contents of an NSCache? 如何观察NSCache的内容?

I would expect NSCache not to be key-value observing (KVO) compliant for that sort of key. 我希望NSCache不会像这种键那样NSCache键值观察(KVO)。 KVO is implemented internally at the NSObject level by replacing the normal setter with one that alerts relevant observers and calls the original setter. KVO在NSObject级别内部实现,将普通的setter替换为警告相关观察者并调用原始setter的setter。 In the case of things you set with setObject:forKey: there is no specific setter so nothing for the runtime to hang off. 对于使用setObject:forKey:设置的内容setObject:forKey:没有特定的setter,因此运行时无需挂起。

Since NSCache doesn't post any relevant notifications I think your best hope is the delegate protocol . 由于NSCache没有发布任何相关通知,我认为您最好的希望是委托协议 It's not explicit exactly what counts as an eviction but if cache:willEvictObject: is called when the object associated with a key is changed on purpose then you could hook directly off that. 它并不明确究竟什么算作驱逐,但如果cache:willEvictObject:在与密钥关联的对象被故意更改时被调用,那么你可以直接挂钩。

Otherwise I'd recommend you create a wrapper class for NSCache , say DWCache for argument's sake, that contains an NSCache , is the delegate of the cache, and provides its own setObject:forKey: . 否则我建议你为NSCache创建一个包装类,为了参数说DWCache ,它包含一个NSCache ,是缓存的委托,并提供它自己的setObject:forKey: . It will posts an appropriate message (i) upon the first call to setObject:forKey:; 它将在第一次调用setObject时发布适当的消息(i):forKey:; (ii) upon every subsequent call that supplies an object different from that already in the cache; (ii)在每次后续呼叫中提供与缓存中已有的对象不同的对象; and (iii) whenever it receives a cache:willEvictObject: . (iii)每当收到cache:willEvictObject: .

The only potential complexity is that NSCache doesn't copy the original keys and, partly as a result, has no means to get key from object. 唯一可能的复杂性是NSCache不复制原始密钥,部分因此无法从对象获取密钥。 You may want to store those connections separately, eg through an NSDictionary . 您可能希望单独存储这些连接,例如通过NSDictionary Provided you clear the dictionary when the cache evicts the object you'll still be providing caching behaviour. 如果您在缓存驱逐对象时清除字典,您仍将提供缓存行为。

You have to implement this method: 你必须实现这个方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

keyPath is the key that changed, object is the new value. keyPath是更改的键,object是新值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM